diff --git a/app/src/main/java/org/opencord/igmpproxy/impl/IgmpSender.java b/app/src/main/java/org/opencord/igmpproxy/impl/IgmpSender.java
new file mode 100644
index 0000000..a4cbaa5
--- /dev/null
+++ b/app/src/main/java/org/opencord/igmpproxy/impl/IgmpSender.java
@@ -0,0 +1,247 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.opencord.igmpproxy.impl;
+
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IGMP;
+import org.onlab.packet.IGMP.IGMPv2;
+import org.onlab.packet.IGMP.IGMPv3;
+import org.onlab.packet.IGMPMembership;
+import org.onlab.packet.IGMPQuery;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.MacAddress;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.packet.DefaultOutboundPacket;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.net.packet.PacketService;
+import org.opencord.igmpproxy.IgmpStatisticsService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.nio.ByteBuffer;
+
+/**
+ *  Message encode and send interface for igmpproxy.
+ */
+public final class IgmpSender {
+    static final String V3_REPORT_ADDRESS = "224.0.0.22";
+    static final String MAC_ADDRESS = "DE:AD:BE:EF:BA:11";
+    static final short DEFAULT_MVLAN = 4000;
+    static final byte DEFAULT_COS = 7;
+    static final int DEFAULT_MEX_RESP = 10;
+    static final byte[] RA_BYTES = {(byte) 0x94, (byte) 0x04, (byte) 0x00, (byte) 0x00};
+
+    private static IgmpSender instance = null;
+    private PacketService packetService;
+    private MastershipService mastershipService;
+    private IgmpStatisticsService igmpStatisticsService;
+    private boolean withRAUplink = true;
+    private boolean withRADownlink = false;
+    private short mvlan = DEFAULT_MVLAN;
+    private byte igmpCos = DEFAULT_COS;
+    private int maxResp = DEFAULT_MEX_RESP;
+    private Logger log = LoggerFactory.getLogger(getClass());
+
+    private IgmpSender(PacketService packetService, MastershipService mastershipService,
+             IgmpStatisticsService igmpStatisticsService) {
+        this.packetService = packetService;
+        this.mastershipService = mastershipService;
+        this.igmpStatisticsService = igmpStatisticsService;
+    }
+
+    public static void init(PacketService packetService, MastershipService mastershipService,
+            IgmpStatisticsService igmpStatisticsService) {
+        instance = new IgmpSender(packetService, mastershipService, igmpStatisticsService);
+    }
+
+    public static IgmpSender getInstance() {
+        return instance;
+    }
+
+    public void setWithRAUplink(boolean withRaUplink) {
+        this.withRAUplink = withRaUplink;
+    }
+
+    public void setWithRADownlink(boolean withRADownlink) {
+        this.withRADownlink = withRADownlink;
+    }
+
+    public void setMvlan(short mvlan) {
+        this.mvlan = mvlan;
+    }
+
+    public void setIgmpCos(byte igmpCos) {
+        this.igmpCos = igmpCos;
+    }
+
+    public void setMaxResp(int maxResp) {
+        this.maxResp = maxResp;
+    }
+
+    public Ethernet buildIgmpV3Join(Ip4Address groupIp, Ip4Address sourceIp) {
+        IGMPMembership igmpMembership = new IGMPMembership(groupIp);
+        igmpMembership.setRecordType(IGMPMembership.CHANGE_TO_EXCLUDE_MODE);
+
+        return buildIgmpPacket(IGMP.TYPE_IGMPV3_MEMBERSHIP_REPORT, groupIp, igmpMembership, sourceIp, false);
+    }
+
+    public Ethernet buildIgmpV3ResponseQuery(Ip4Address groupIp, Ip4Address sourceIp) {
+        IGMPMembership igmpMembership = new IGMPMembership(groupIp);
+        igmpMembership.setRecordType(IGMPMembership.MODE_IS_EXCLUDE);
+
+        return buildIgmpPacket(IGMP.TYPE_IGMPV3_MEMBERSHIP_REPORT, groupIp, igmpMembership, sourceIp, false);
+    }
+
+    public Ethernet buildIgmpV3Leave(Ip4Address groupIp, Ip4Address sourceIp) {
+        IGMPMembership igmpMembership = new IGMPMembership(groupIp);
+        igmpMembership.setRecordType(IGMPMembership.CHANGE_TO_INCLUDE_MODE);
+
+        return buildIgmpPacket(IGMP.TYPE_IGMPV3_MEMBERSHIP_REPORT, groupIp, igmpMembership, sourceIp, false);
+    }
+
+    public Ethernet buildIgmpV2Query(Ip4Address groupIp, Ip4Address sourceIp) {
+        return buildIgmpPacket(IGMP.TYPE_IGMPV3_MEMBERSHIP_QUERY, groupIp, null, sourceIp, true);
+    }
+
+    public Ethernet buildIgmpV3Query(Ip4Address groupIp, Ip4Address sourceIp) {
+        return buildIgmpPacket(IGMP.TYPE_IGMPV3_MEMBERSHIP_QUERY, groupIp, null, sourceIp, false);
+    }
+
+    protected Ethernet buildIgmpPacket(byte type, Ip4Address groupIp, IGMPMembership igmpMembership,
+                                     Ip4Address sourceIp, boolean isV2Query) {
+
+        IGMP igmpPacket;
+        if (isV2Query) {
+            igmpPacket = new IGMP.IGMPv2();
+        } else {
+            igmpPacket = new IGMP.IGMPv3();
+        }
+
+        IPv4 ip4Packet = new IPv4();
+        Ethernet ethPkt = new Ethernet();
+
+        igmpPacket.setIgmpType(type);
+
+        switch (type) {
+            case IGMP.TYPE_IGMPV3_MEMBERSHIP_QUERY:
+                igmpPacket.setMaxRespCode((byte) (maxResp * 10));
+                IGMPQuery igmpQuery = new IGMPQuery(groupIp, 0);
+
+                igmpPacket.addGroup(igmpQuery);
+                ip4Packet.setDestinationAddress(groupIp.toInt());
+                if (withRADownlink) {
+                    ip4Packet.setOptions(RA_BYTES);
+                }
+                break;
+
+            case IGMP.TYPE_IGMPV3_MEMBERSHIP_REPORT:
+                if (igmpMembership == null) {
+                    return null;
+                }
+                igmpPacket.addGroup(igmpMembership);
+                if (type == IGMP.TYPE_IGMPV3_MEMBERSHIP_REPORT) {
+                    ip4Packet.setDestinationAddress(Ip4Address.valueOf(V3_REPORT_ADDRESS).toInt());
+                } else {
+                    ip4Packet.setDestinationAddress(groupIp.toInt());
+                }
+                if (withRAUplink) {
+                    ip4Packet.setOptions(RA_BYTES);
+                }
+                break;
+
+            case IGMP.TYPE_IGMPV2_MEMBERSHIP_REPORT:
+            case IGMP.TYPE_IGMPV2_LEAVE_GROUP:
+                return null;
+            default:
+                igmpStatisticsService.getIgmpStats().increaseUnknownIgmpTypePacketsRxCounter();
+                return null;
+        }
+
+        igmpPacket.setParent(ip4Packet);
+        ip4Packet.setSourceAddress(sourceIp.toInt());
+        ip4Packet.setProtocol(IPv4.PROTOCOL_IGMP);
+        ip4Packet.setPayload(igmpPacket);
+        ip4Packet.setParent(ethPkt);
+        ip4Packet.setTtl((byte) 0x78);
+
+        ethPkt.setDestinationMACAddress(multiaddToMac(ip4Packet.getDestinationAddress()));
+        ethPkt.setSourceMACAddress(MAC_ADDRESS);
+        ethPkt.setEtherType(Ethernet.TYPE_IPV4);
+        ethPkt.setPayload(ip4Packet);
+        ethPkt.setVlanID(mvlan);
+        ethPkt.setPriorityCode(igmpCos);
+
+        return ethPkt;
+    }
+
+    private MacAddress multiaddToMac(int multiaddress) {
+        byte[] b = new byte[3];
+        b[0] = (byte) (multiaddress & 0xff);
+        b[1] = (byte) (multiaddress >> 8 & 0xff);
+        b[2] = (byte) (multiaddress >> 16 & 0x7f);
+        byte[] macByte = {0x01, 0x00, 0x5e, b[2], b[1], b[0]};
+
+        MacAddress mac = MacAddress.valueOf(macByte);
+        return mac;
+    }
+
+    public void sendIgmpPacketUplink(Ethernet ethPkt, DeviceId deviceId, PortNumber upLinkPort) {
+        if (!mastershipService.isLocalMaster(deviceId)) {
+            return;
+        }
+
+        if (IgmpManager.connectPointMode) {
+            if (IgmpManager.connectPoint == null) {
+                log.warn("cannot find a connectPoint to send the packet uplink");
+                return;
+            }
+            sendIgmpPacket(ethPkt, IgmpManager.connectPoint.deviceId(), IgmpManager.connectPoint.port());
+        } else {
+            sendIgmpPacket(ethPkt, deviceId, upLinkPort);
+        }
+    }
+
+    public void sendIgmpPacket(Ethernet ethPkt, DeviceId deviceId, PortNumber portNumber) {
+        if (!mastershipService.isLocalMaster(deviceId)) {
+            return;
+        }
+
+        IPv4 ipv4Pkt = (IPv4) ethPkt.getPayload();
+        IGMP igmp = (IGMP) ipv4Pkt.getPayload();
+        // We are checking the length of packets. Right now the counter value will be 0 because of internal translation
+        // As packet length will always be valid
+        // This counter will be useful in future if we change the procedure to generate the packets.
+        if ((igmp.getIgmpType() == IGMP.TYPE_IGMPV2_MEMBERSHIP_REPORT
+             || igmp.getIgmpType() == IGMP.TYPE_IGMPV2_LEAVE_GROUP) && igmp.serialize().length < IGMPv2.HEADER_LENGTH) {
+                 igmpStatisticsService.getIgmpStats().increaseInvalidIgmpLength();
+        } else if (igmp.getIgmpType() == IGMP.TYPE_IGMPV3_MEMBERSHIP_REPORT
+            && igmp.serialize().length < IGMPv3.MINIMUM_HEADER_LEN) {
+                 igmpStatisticsService.getIgmpStats().increaseInvalidIgmpLength();
+        }
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                .setOutput(portNumber).build();
+        OutboundPacket packet = new DefaultOutboundPacket(deviceId,
+                treatment, ByteBuffer.wrap(ethPkt.serialize()));
+        igmpStatisticsService.getIgmpStats().increaseValidIgmpPacketCounter();
+        packetService.emit(packet);
+
+    }
+}
