diff --git a/app/src/main/java/org/onosproject/segmentrouting/xconnect/api/XconnectService.java b/app/src/main/java/org/onosproject/segmentrouting/xconnect/api/XconnectService.java
index 25f1b01..4e82524 100644
--- a/app/src/main/java/org/onosproject/segmentrouting/xconnect/api/XconnectService.java
+++ b/app/src/main/java/org/onosproject/segmentrouting/xconnect/api/XconnectService.java
@@ -22,6 +22,7 @@
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.PortNumber;
 
+import java.util.List;
 import java.util.Set;
 
 /**
@@ -73,6 +74,24 @@
     boolean hasXconnect(ConnectPoint cp);
 
     /**
+     * Gives xconnect VLAN of given port of a device.
+     *
+     * @param deviceId Device ID
+     * @param port Port number
+     * @return true if given VLAN vlanId is XConnect VLAN on device deviceId.
+     */
+    List<VlanId> getXconnectVlans(DeviceId deviceId, PortNumber port);
+
+    /**
+     * Checks given VLAN is XConnect VLAN in given device.
+     *
+     * @param deviceId Device ID
+     * @param vlanId VLAN ID
+     * @return true if given VLAN vlanId is XConnect VLAN on device deviceId.
+     */
+    boolean isXconnectVlan(DeviceId deviceId, VlanId vlanId);
+
+    /**
      * Returns the Xconnect next objective store.
      *
      * @return current contents of the xconnectNextObjStore
@@ -86,4 +105,12 @@
      */
     void removeNextId(int nextId);
 
+    /**
+     * Returns Xconnect next objective ID associated with group device + vlan.
+     *
+     * @param deviceId - Device ID
+     * @param vlanId - VLAN ID
+     * @return Current associated group ID
+     */
+    int getNextId(DeviceId deviceId, VlanId vlanId);
 }
diff --git a/app/src/main/java/org/onosproject/segmentrouting/xconnect/impl/XconnectManager.java b/app/src/main/java/org/onosproject/segmentrouting/xconnect/impl/XconnectManager.java
index a7eb664..b65faa9 100644
--- a/app/src/main/java/org/onosproject/segmentrouting/xconnect/impl/XconnectManager.java
+++ b/app/src/main/java/org/onosproject/segmentrouting/xconnect/impl/XconnectManager.java
@@ -24,6 +24,7 @@
 import org.apache.felix.scr.annotations.Reference;
 import org.apache.felix.scr.annotations.ReferenceCardinality;
 import org.apache.felix.scr.annotations.Service;
+import org.onlab.packet.Ethernet;
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.VlanId;
 import org.onlab.util.KryoNamespace;
@@ -33,6 +34,8 @@
 import org.onosproject.mastership.MastershipService;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostLocation;
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.config.NetworkConfigService;
 import org.onosproject.net.device.DeviceEvent;
@@ -54,7 +57,12 @@
 import org.onosproject.net.flowobjective.Objective;
 import org.onosproject.net.flowobjective.ObjectiveContext;
 import org.onosproject.net.flowobjective.ObjectiveError;
+import org.onosproject.net.host.HostEvent;
+import org.onosproject.net.host.HostListener;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.intf.InterfaceService;
 import org.onosproject.segmentrouting.SegmentRoutingService;
+import org.onosproject.segmentrouting.storekey.VlanNextObjectiveStoreKey;
 import org.onosproject.segmentrouting.xconnect.api.XconnectCodec;
 import org.onosproject.segmentrouting.xconnect.api.XconnectDesc;
 import org.onosproject.segmentrouting.xconnect.api.XconnectKey;
@@ -70,6 +78,11 @@
 import org.slf4j.LoggerFactory;
 
 import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutorService;
@@ -107,6 +120,12 @@
     @Reference(cardinality = ReferenceCardinality.OPTIONAL_UNARY)
     public SegmentRoutingService srService;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    public InterfaceService interfaceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    HostService hostService;
+
     private static final String APP_NAME = "org.onosproject.xconnect";
     private static final String ERROR_NOT_MASTER = "Not master controller";
 
@@ -116,11 +135,18 @@
     private ConsistentMap<XconnectKey, Set<PortNumber>> xconnectStore;
     private ConsistentMap<XconnectKey, Integer> xconnectNextObjStore;
 
+    private ConsistentMap<VlanNextObjectiveStoreKey, Integer> xconnectMulticastNextStore;
+    private ConsistentMap<VlanNextObjectiveStoreKey, List<PortNumber>> xconnectMulticastPortsStore;
+
     private final MapEventListener<XconnectKey, Set<PortNumber>> xconnectListener = new XconnectMapListener();
     private final DeviceListener deviceListener = new InternalDeviceListener();
 
     private ExecutorService deviceEventExecutor;
 
+    private final HostListener hostListener = new InternalHostListener();
+    private ExecutorService hostEventExecutor;
+
+
     @Activate
     void activate() {
         appId = coreService.registerApplication(APP_NAME);
@@ -129,7 +155,8 @@
         KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
                 .register(KryoNamespaces.API)
                 .register(XconnectManager.class)
-                .register(XconnectKey.class);
+                .register(XconnectKey.class)
+                .register(VlanNextObjectiveStoreKey.class);
 
         xconnectStore = storageService.<XconnectKey, Set<PortNumber>>consistentMapBuilder()
                 .withName("onos-sr-xconnect")
@@ -144,11 +171,25 @@
                 .withSerializer(Serializer.using(serializer.build()))
                 .build();
 
+        xconnectMulticastNextStore = storageService.<VlanNextObjectiveStoreKey, Integer>consistentMapBuilder()
+                .withName("onos-sr-xconnect-l2multicast-next")
+                .withSerializer(Serializer.using(serializer.build()))
+                .build();
+        xconnectMulticastPortsStore = storageService.<VlanNextObjectiveStoreKey, List<PortNumber>>consistentMapBuilder()
+                .withName("onos-sr-xconnect-l2multicast-ports")
+                .withSerializer(Serializer.using(serializer.build()))
+                .build();
+
         deviceEventExecutor = Executors.newSingleThreadScheduledExecutor(
                 groupedThreads("sr-xconnect-device-event", "%d", log));
 
         deviceService.addListener(deviceListener);
 
+        hostEventExecutor = Executors.newSingleThreadExecutor(
+                groupedThreads("sr-xconnect-host-event", "%d", log));
+
+        hostService.addListener(hostListener);
+
         log.info("Started");
     }
 
@@ -156,9 +197,11 @@
     void deactivate() {
         xconnectStore.removeListener(xconnectListener);
         deviceService.removeListener(deviceListener);
+        hostService.removeListener(hostListener);
         codecService.unregisterCodec(XconnectDesc.class);
 
         deviceEventExecutor.shutdown();
+        hostEventExecutor.shutdown();
 
         log.info("Stopped");
     }
@@ -166,7 +209,7 @@
     @Override
     public void addOrUpdateXconnect(DeviceId deviceId, VlanId vlanId, Set<PortNumber> ports) {
         log.info("Adding or updating xconnect. deviceId={}, vlanId={}, ports={}",
-                deviceId, vlanId, ports);
+                 deviceId, vlanId, ports);
         final XconnectKey key = new XconnectKey(deviceId, vlanId);
         xconnectStore.put(key, ports);
     }
@@ -174,9 +217,15 @@
     @Override
     public void removeXonnect(DeviceId deviceId, VlanId vlanId) {
         log.info("Removing xconnect. deviceId={}, vlanId={}",
-                deviceId, vlanId);
+                 deviceId, vlanId);
         final XconnectKey key = new XconnectKey(deviceId, vlanId);
         xconnectStore.remove(key);
+
+        // Cleanup multicasting support, if any.
+        srService.getPairDeviceId(deviceId).ifPresent(pairDeviceId -> {
+            cleanupL2MulticastRule(pairDeviceId, srService.getPairLocalPort(pairDeviceId).get(), vlanId, true);
+        });
+
     }
 
     @Override
@@ -189,11 +238,27 @@
     @Override
     public boolean hasXconnect(ConnectPoint cp) {
         return getXconnects().stream().anyMatch(desc ->
-                desc.key().deviceId().equals(cp.deviceId()) && desc.ports().contains(cp.port())
+                                                        desc.key().deviceId().equals(cp.deviceId())
+                                                                && desc.ports().contains(cp.port())
         );
     }
 
     @Override
+    public List<VlanId> getXconnectVlans(DeviceId deviceId, PortNumber port) {
+        return getXconnects().stream()
+                .filter(desc -> desc.key().deviceId().equals(deviceId) && desc.ports().contains(port))
+                .map(XconnectDesc::key)
+                .map(XconnectKey::vlanId)
+                .collect(Collectors.toList());
+    }
+
+    @Override
+    public boolean isXconnectVlan(DeviceId deviceId, VlanId vlanId) {
+        return getXconnects().stream()
+                .anyMatch(desc -> desc.key().deviceId().equals(deviceId) && desc.key().vlanId().equals(vlanId));
+    }
+
+    @Override
     public ImmutableMap<XconnectKey, Integer> getNext() {
         if (xconnectNextObjStore != null) {
             return ImmutableMap.copyOf(xconnectNextObjStore.asJavaMap());
@@ -203,6 +268,15 @@
     }
 
     @Override
+    public int getNextId(final DeviceId deviceId, final VlanId vlanId) {
+        Optional<Integer> nextObjective = getNext().entrySet().stream()
+                .filter(d -> d.getKey().deviceId().equals(deviceId) && d.getKey().vlanId().equals(vlanId))
+                .findFirst()
+                .map(Map.Entry::getValue);
+        return nextObjective.isPresent() ? nextObjective.get() : -1;
+    }
+
+    @Override
     public void removeNextId(int nextId) {
         xconnectNextObjStore.entrySet().forEach(e -> {
             if (e.getValue().value() == nextId) {
@@ -260,6 +334,98 @@
         }
     }
 
+    private class InternalHostListener implements HostListener {
+        @Override
+        public void event(HostEvent event) {
+            hostEventExecutor.execute(() -> {
+
+                switch (event.type()) {
+                    case HOST_MOVED:
+                        log.trace("Processing host event {}", event);
+
+                        Host host = event.subject();
+                        Set<HostLocation> prevLocations = event.prevSubject().locations();
+                        Set<HostLocation> newLocations = host.locations();
+
+                        // Dual-home host port failure
+                        // For each old location, in failed and paired devices update L2 vlan groups
+                        Sets.difference(prevLocations, newLocations).forEach(prevLocation -> {
+
+                            Optional<DeviceId> pairDeviceId = srService.getPairDeviceId(prevLocation.deviceId());
+                            Optional<PortNumber> pairLocalPort = srService.getPairLocalPort(prevLocation.deviceId());
+
+                            if (pairDeviceId.isPresent() && pairLocalPort.isPresent() && newLocations.stream()
+                                    .anyMatch(location -> location.deviceId().equals(pairDeviceId.get())) &&
+                                    hasXconnect(new ConnectPoint(prevLocation.deviceId(), prevLocation.port()))) {
+
+                                List<VlanId> xconnectVlans = getXconnectVlans(prevLocation.deviceId(),
+                                                                              prevLocation.port());
+                                xconnectVlans.forEach(xconnectVlan -> {
+                                    // Add single-home host into L2 multicast group at paired device side.
+                                    // Also append ACL rule to forward traffic from paired port to L2 multicast group.
+                                    newLocations.stream()
+                                            .filter(location -> location.deviceId().equals(pairDeviceId.get()))
+                                            .forEach(location -> populateL2Multicast(location.deviceId(),
+                                                                                     srService.getPairLocalPort(
+                                                                                             location.deviceId()).get(),
+                                                                                     xconnectVlan,
+                                                                                     Collections.singletonList(
+                                                                                             location.port())));
+                               // Ensure pair-port attached to xconnect vlan flooding group at dual home failed device.
+                                    updateL2Flooding(prevLocation.deviceId(), pairLocalPort.get(), xconnectVlan, true);
+                                });
+                            }
+                        });
+
+                        // Dual-home host port restoration
+                        // For each new location, reverse xconnect loop prevention groups.
+                        Sets.difference(newLocations, prevLocations).forEach(newLocation -> {
+                            final Optional<DeviceId> pairDeviceId = srService.getPairDeviceId(newLocation.deviceId());
+                            Optional<PortNumber> pairLocalPort = srService.getPairLocalPort(newLocation.deviceId());
+                            if (pairDeviceId.isPresent() && pairLocalPort.isPresent() &&
+                                    hasXconnect((new ConnectPoint(newLocation.deviceId(), newLocation.port())))) {
+
+                                List<VlanId> xconnectVlans = getXconnectVlans(newLocation.deviceId(),
+                                                                              newLocation.port());
+                                xconnectVlans.forEach(xconnectVlan -> {
+                                    // Remove recovered dual homed port from vlan L2 multicast group
+                                    prevLocations.stream()
+                                            .filter(prevLocation -> prevLocation.deviceId().equals(pairDeviceId.get()))
+                                            .forEach(prevLocation -> revokeL2Multicast(prevLocation.deviceId(),
+                                                                                 srService.getPairLocalPort(
+                                                                                       prevLocation.deviceId()).get(),
+                                                                                       xconnectVlan,
+                                                                      Collections.singletonList(newLocation.port()))
+                                            );
+
+                                 // Remove pair-port from vlan's flooding group at dual home restored device,if needed.
+                                    if (!hasAccessPortInMulticastGroup(newLocation.deviceId(),
+                                                                       xconnectVlan,
+                                                                       pairLocalPort.get())) {
+                                        updateL2Flooding(newLocation.deviceId(),
+                                                         pairLocalPort.get(),
+                                                         xconnectVlan,
+                                                         false);
+
+                                        // Clean L2 multicast group at pair-device; also update store.
+                                        cleanupL2MulticastRule(pairDeviceId.get(),
+                                                               srService.getPairLocalPort(pairDeviceId.get()).get(),
+                                                               xconnectVlan,
+                                                               false);
+                                    }
+                                });
+                            }
+                        });
+                        break;
+
+                    default:
+                        log.warn("Unsupported host event type: {} received. Ignoring.", event.type());
+                        break;
+                }
+            });
+        }
+    }
+
     private void init(DeviceId deviceId) {
         getXconnects().stream()
                 .filter(desc -> desc.key().deviceId().equals(deviceId))
@@ -276,7 +442,7 @@
     /**
      * Populates XConnect groups and flows for given key.
      *
-     * @param key XConnect key
+     * @param key   XConnect key
      * @param ports a set of ports to be cross-connected
      */
     private void populateXConnect(XconnectKey key, Set<PortNumber> ports) {
@@ -285,7 +451,6 @@
             return;
         }
 
-        ports = addPairPort(key.deviceId(), ports);
         populateFilter(key, ports);
         populateFwd(key, populateNext(key, ports));
         populateAcl(key);
@@ -294,7 +459,7 @@
     /**
      * Populates filtering objectives for given XConnect.
      *
-     * @param key XConnect store key
+     * @param key   XConnect store key
      * @param ports XConnect ports
      */
     private void populateFilter(XconnectKey key, Set<PortNumber> ports) {
@@ -302,10 +467,10 @@
             FilteringObjective.Builder filtObjBuilder = filterObjBuilder(key, port);
             ObjectiveContext context = new DefaultObjectiveContext(
                     (objective) -> log.debug("XConnect FilterObj for {} on port {} populated",
-                            key, port),
+                                             key, port),
                     (objective, error) ->
                             log.warn("Failed to populate XConnect FilterObj for {} on port {}: {}",
-                                    key, port, error));
+                                     key, port, error));
             flowObjectiveService.filter(key.deviceId(), filtObjBuilder.add(context));
         });
     }
@@ -313,7 +478,7 @@
     /**
      * Populates next objectives for given XConnect.
      *
-     * @param key XConnect store key
+     * @param key   XConnect store key
      * @param ports XConnect ports
      */
     private int populateNext(XconnectKey key, Set<PortNumber> ports) {
@@ -342,7 +507,7 @@
     /**
      * Populates bridging forwarding objectives for given XConnect.
      *
-     * @param key XConnect store key
+     * @param key    XConnect store key
      * @param nextId next objective id
      */
     private void populateFwd(XconnectKey key, int nextId) {
@@ -371,7 +536,7 @@
     /**
      * Revokes XConnect groups and flows for given key.
      *
-     * @param key XConnect key
+     * @param key   XConnect key
      * @param ports XConnect ports
      */
     private void revokeXConnect(XconnectKey key, Set<PortNumber> ports) {
@@ -380,7 +545,6 @@
             return;
         }
 
-        ports = addPairPort(key.deviceId(), ports);
         revokeFilter(key, ports);
         if (xconnectNextObjStore.containsKey(key)) {
             int nextId = xconnectNextObjStore.get(key).value();
@@ -395,7 +559,7 @@
     /**
      * Revokes filtering objectives for given XConnect.
      *
-     * @param key XConnect store key
+     * @param key   XConnect store key
      * @param ports XConnect ports
      */
     private void revokeFilter(XconnectKey key, Set<PortNumber> ports) {
@@ -403,10 +567,10 @@
             FilteringObjective.Builder filtObjBuilder = filterObjBuilder(key, port);
             ObjectiveContext context = new DefaultObjectiveContext(
                     (objective) -> log.debug("XConnect FilterObj for {} on port {} revoked",
-                            key, port),
+                                             key, port),
                     (objective, error) ->
                             log.warn("Failed to revoke XConnect FilterObj for {} on port {}: {}",
-                                    key, port, error));
+                                     key, port, error));
             flowObjectiveService.filter(key.deviceId(), filtObjBuilder.remove(context));
         });
     }
@@ -414,9 +578,9 @@
     /**
      * Revokes next objectives for given XConnect.
      *
-     * @param key XConnect store key
-     * @param ports ports in the XConnect
-     * @param nextId next objective id
+     * @param key        XConnect store key
+     * @param ports      ports in the XConnect
+     * @param nextId     next objective id
      * @param nextFuture completable future for this next objective operation
      */
     private void revokeNext(XconnectKey key, Set<PortNumber> ports, int nextId,
@@ -446,8 +610,8 @@
     /**
      * Revokes bridging forwarding objectives for given XConnect.
      *
-     * @param key XConnect store key
-     * @param nextId next objective id
+     * @param key       XConnect store key
+     * @param nextId    next objective id
      * @param fwdFuture completable future for this forwarding objective operation
      */
     private void revokeFwd(XconnectKey key, int nextId, CompletableFuture<ObjectiveError> fwdFuture) {
@@ -489,9 +653,9 @@
     /**
      * Updates XConnect groups and flows for given key.
      *
-     * @param key XConnect key
+     * @param key       XConnect key
      * @param prevPorts previous XConnect ports
-     * @param ports new XConnect ports
+     * @param ports     new XConnect ports
      */
     private void updateXConnect(XconnectKey key, Set<PortNumber> prevPorts,
                                 Set<PortNumber> ports) {
@@ -500,10 +664,12 @@
 
         // remove old filter
         prevPorts.stream().filter(port -> !ports.contains(port)).forEach(port ->
-                revokeFilter(key, ImmutableSet.of(port)));
+                                                                                 revokeFilter(key,
+                                                                                              ImmutableSet.of(port)));
         // install new filter
         ports.stream().filter(port -> !prevPorts.contains(port)).forEach(port ->
-                populateFilter(key, ImmutableSet.of(port)));
+                                                                                 populateFilter(key,
+                                                                                                ImmutableSet.of(port)));
 
         CompletableFuture<ObjectiveError> fwdFuture = new CompletableFuture<>();
         CompletableFuture<ObjectiveError> nextFuture = new CompletableFuture<>();
@@ -533,8 +699,8 @@
     /**
      * Creates a next objective builder for XConnect with given nextId.
      *
-     * @param key XConnect key
-     * @param ports set of XConnect ports
+     * @param key    XConnect key
+     * @param ports  set of XConnect ports
      * @param nextId next objective id
      * @return next objective builder
      */
@@ -556,7 +722,7 @@
     /**
      * Creates a next objective builder for XConnect.
      *
-     * @param key XConnect key
+     * @param key   XConnect key
      * @param ports set of XConnect ports
      * @return next objective builder
      */
@@ -569,7 +735,7 @@
     /**
      * Creates a bridging forwarding objective builder for XConnect.
      *
-     * @param key XConnect key
+     * @param key    XConnect key
      * @param nextId next ID of the broadcast group for this XConnect key
      * @return forwarding objective builder
      */
@@ -617,7 +783,7 @@
     /**
      * Creates a filtering objective builder for XConnect.
      *
-     * @param key XConnect key
+     * @param key  XConnect key
      * @param port XConnect ports
      * @return next objective builder
      */
@@ -631,18 +797,320 @@
     }
 
     /**
-     * Add pair port to the given set of port.
+     * Updates L2 flooding groups; add pair link into L2 flooding group of given xconnect vlan.
      *
-     * @param deviceId device Id
-     * @param ports ports specified in the xconnect config
-     * @return port specified in the xconnect config plus the pair port (if configured)
+     * @param deviceId Device ID
+     * @param port     Port details
+     * @param vlanId   VLAN ID
+     * @param install  Whether to add or revoke pair link addition to flooding group
      */
-    private Set<PortNumber> addPairPort(DeviceId deviceId, Set<PortNumber> ports) {
-        if (srService == null) {
-            return ports;
+    private void updateL2Flooding(DeviceId deviceId, final PortNumber port, VlanId vlanId, boolean install) {
+
+        // Ensure mastership on device
+        if (!mastershipService.isLocalMaster(deviceId)) {
+            return;
         }
-        Set<PortNumber> newPorts = Sets.newHashSet(ports);
-        srService.getPairLocalPort(deviceId).ifPresent(newPorts::add);
-        return newPorts;
+
+        // Locate L2 flooding group details for given xconnect vlan
+        int nextId = getNextId(deviceId, vlanId);
+        if (nextId == -1) {
+            log.debug("XConnect vlan {} broadcast group for device {} doesn't exists. " +
+                              "Aborting pair group linking.", vlanId, deviceId);
+            return;
+        }
+
+        // Add pairing-port group to flooding group
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+        // treatment.popVlan();
+        treatment.setOutput(port);
+        ObjectiveContext context = new DefaultObjectiveContext(
+                (objective) ->
+                        log.debug("Pair port added/removed to vlan {} next objective {} on {}",
+                                  vlanId, nextId, deviceId),
+                (objective, error) ->
+                        log.warn("Failed adding/removing pair port to vlan {} next objective {} on {}." +
+                                         "Error : {}", vlanId, nextId, deviceId, error)
+        );
+        NextObjective.Builder vlanNextObjectiveBuilder = DefaultNextObjective.builder()
+                .withId(nextId)
+                .withType(NextObjective.Type.BROADCAST)
+                .fromApp(srService.appId())
+                .withMeta(DefaultTrafficSelector.builder().matchVlanId(vlanId).build())
+                .addTreatment(treatment.build());
+        if (install) {
+            flowObjectiveService.next(deviceId, vlanNextObjectiveBuilder.addToExisting(context));
+        } else {
+            flowObjectiveService.next(deviceId, vlanNextObjectiveBuilder.removeFromExisting(context));
+        }
+        log.debug("Submitted next objective {} for vlan: {} in device {}",
+                  nextId, vlanId, deviceId);
     }
+
+    /**
+     * Populate L2 multicast rule on given deviceId that matches given mac, given vlan and
+     * output to given port's L2 mulitcast group.
+     *
+     * @param deviceId    Device ID
+     * @param pairPort    Pair port number
+     * @param vlanId      VLAN ID
+     * @param accessPorts List of access ports to be added into L2 multicast group
+     */
+    private void populateL2Multicast(DeviceId deviceId, final PortNumber pairPort,
+                             VlanId vlanId, List<PortNumber> accessPorts) {
+
+        boolean multicastGroupExists = true;
+        int vlanMulticastNextId;
+
+        // Ensure enough rights to program pair device
+        if (!srService.shouldProgram(deviceId)) {
+            return;
+        }
+
+        // Step 1 : Populate single homed access ports into vlan's L2 multicast group
+        NextObjective.Builder vlanMulticastNextObjBuilder = DefaultNextObjective
+                .builder()
+                .withType(NextObjective.Type.BROADCAST)
+                .fromApp(srService.appId())
+            .withMeta(DefaultTrafficSelector.builder().matchVlanId(vlanId)
+                          .matchEthDst(MacAddress.IPV4_MULTICAST).build());
+        vlanMulticastNextId = getMulticastGroupNextObjectiveId(deviceId, vlanId);
+        if (vlanMulticastNextId == -1) {
+            // Vlan's L2 multicast group doesn't exist; create it, update store and add pair port as sub-group
+            multicastGroupExists = false;
+            vlanMulticastNextId = flowObjectiveService.allocateNextId();
+            addMulticastGroupNextObjectiveId(deviceId, vlanId, vlanMulticastNextId);
+            vlanMulticastNextObjBuilder.addTreatment(
+                    DefaultTrafficTreatment.builder().popVlan().setOutput(pairPort).build()
+            );
+        }
+        vlanMulticastNextObjBuilder.withId(vlanMulticastNextId);
+        final int nextId = vlanMulticastNextId;
+        accessPorts.forEach(p -> {
+            TrafficTreatment.Builder egressAction = DefaultTrafficTreatment.builder();
+            // Do vlan popup action based on interface configuration
+            if (interfaceService.getInterfacesByPort(new ConnectPoint(deviceId, p))
+                    .stream().noneMatch(i -> i.vlanTagged().contains(vlanId))) {
+                egressAction.popVlan();
+            }
+            egressAction.setOutput(p);
+            vlanMulticastNextObjBuilder.addTreatment(egressAction.build());
+            addMulticastGroupPort(deviceId, vlanId, p);
+        });
+        ObjectiveContext context = new DefaultObjectiveContext(
+                (objective) ->
+                        log.debug("L2 multicast group installed/updated. "
+                                          + "NextObject Id {} on {} for subnet {} ",
+                                  nextId, deviceId, vlanId),
+                (objective, error) ->
+                        log.warn("L2 multicast group failed to install/update. "
+                                         + " NextObject Id {} on {} for subnet {} : {}",
+                                 nextId, deviceId, vlanId, error)
+        );
+        if (!multicastGroupExists) {
+            flowObjectiveService.next(deviceId, vlanMulticastNextObjBuilder.add(context));
+
+            // Step 2 : Populate ACL rule; selector = vlan + pair-port, output = vlan L2 multicast group
+            TrafficSelector.Builder multicastSelector = DefaultTrafficSelector.builder();
+            multicastSelector.matchEthType(Ethernet.TYPE_VLAN);
+            multicastSelector.matchInPort(pairPort);
+            multicastSelector.matchVlanId(vlanId);
+            ForwardingObjective.Builder vlanMulticastForwardingObj = DefaultForwardingObjective.builder()
+                    .withFlag(ForwardingObjective.Flag.VERSATILE)
+                    .nextStep(vlanMulticastNextId)
+                    .withSelector(multicastSelector.build())
+                    .withPriority(100)
+                    .fromApp(srService.appId())
+                    .makePermanent();
+            context = new DefaultObjectiveContext(
+                    (objective) -> log.debug("L2 multicasting versatile rule for device {}, port/vlan {}/{} populated",
+                                             deviceId,
+                                             pairPort,
+                                             vlanId),
+                    (objective, error) -> log.warn("Failed to populate L2 multicasting versatile rule for device {}, " +
+                                                           "ports/vlan {}/{}: {}", deviceId, pairPort, vlanId, error));
+            flowObjectiveService.forward(deviceId, vlanMulticastForwardingObj.add(context));
+        } else {
+            // L2_MULTICAST & BROADCAST are similar structure in subgroups; so going with BROADCAST type.
+            vlanMulticastNextObjBuilder.withType(NextObjective.Type.BROADCAST);
+            flowObjectiveService.next(deviceId, vlanMulticastNextObjBuilder.addToExisting(context));
+        }
+    }
+
+    /**
+     * Removes access ports from VLAN L2 multicast group on given deviceId.
+     *
+     * @param deviceId    Device ID
+     * @param pairPort    Pair port number
+     * @param vlanId      VLAN ID
+     * @param accessPorts List of access ports to be added into L2 multicast group
+     */
+    private void revokeL2Multicast(DeviceId deviceId, final PortNumber pairPort,
+                           VlanId vlanId, List<PortNumber> accessPorts) {
+
+        // Ensure enough rights to program pair device
+        if (!srService.shouldProgram(deviceId)) {
+            return;
+        }
+
+        int vlanMulticastNextId = getMulticastGroupNextObjectiveId(deviceId, vlanId);
+        if (vlanMulticastNextId == -1) {
+            return;
+        }
+        NextObjective.Builder vlanMulticastNextObjBuilder = DefaultNextObjective
+                .builder()
+                .withType(NextObjective.Type.BROADCAST)
+                .fromApp(srService.appId())
+                .withMeta(DefaultTrafficSelector.builder().matchVlanId(vlanId).build())
+                .withId(vlanMulticastNextId);
+        accessPorts.forEach(p -> {
+            TrafficTreatment.Builder egressAction = DefaultTrafficTreatment.builder();
+            // Do vlan popup action based on interface configuration
+            if (interfaceService.getInterfacesByPort(new ConnectPoint(deviceId, p))
+                    .stream().noneMatch(i -> i.vlanTagged().contains(vlanId))) {
+                egressAction.popVlan();
+            }
+            egressAction.setOutput(p);
+            vlanMulticastNextObjBuilder.addTreatment(egressAction.build());
+            removeMulticastGroupPort(deviceId, vlanId, p);
+        });
+        ObjectiveContext context = new DefaultObjectiveContext(
+                (objective) ->
+                        log.debug("L2 multicast group installed/updated. "
+                                          + "NextObject Id {} on {} for subnet {} ",
+                                  vlanMulticastNextId, deviceId, vlanId),
+                (objective, error) ->
+                        log.warn("L2 multicast group failed to install/update. "
+                                         + " NextObject Id {} on {} for subnet {} : {}",
+                                 vlanMulticastNextId, deviceId, vlanId, error)
+        );
+        flowObjectiveService.next(deviceId, vlanMulticastNextObjBuilder.removeFromExisting(context));
+    }
+
+    /**
+     * Cleans up VLAN L2 multicast group on given deviceId. ACL rules for the group will also be deleted.
+     * Normally multicast group is not removed if it contains access ports; which can be forced
+     * by "force" flag
+     *
+     * @param deviceId Device ID
+     * @param pairPort Pair port number
+     * @param vlanId   VLAN ID
+     * @param force    Forceful removal
+     */
+    private void cleanupL2MulticastRule(DeviceId deviceId, PortNumber pairPort, VlanId vlanId, boolean force) {
+
+        // Ensure enough rights to program pair device
+        if (!srService.shouldProgram(deviceId)) {
+            return;
+        }
+
+        // Ensure L2 multicast group doesn't contain access ports
+        if (hasAccessPortInMulticastGroup(deviceId, vlanId, pairPort) && !force) {
+            return;
+        }
+
+        // Load L2 multicast group details
+        int vlanMulticastNextId = getMulticastGroupNextObjectiveId(deviceId, vlanId);
+        if (vlanMulticastNextId == -1) {
+            return;
+        }
+
+        // Step 1 : Clear ACL rule; selector = vlan + pair-port, output = vlan L2 multicast group
+        TrafficSelector.Builder l2MulticastSelector = DefaultTrafficSelector.builder();
+        l2MulticastSelector.matchEthType(Ethernet.TYPE_VLAN);
+        l2MulticastSelector.matchInPort(pairPort);
+        l2MulticastSelector.matchVlanId(vlanId);
+        ForwardingObjective.Builder vlanMulticastForwardingObj = DefaultForwardingObjective.builder()
+                .withFlag(ForwardingObjective.Flag.VERSATILE)
+                .nextStep(vlanMulticastNextId)
+                .withSelector(l2MulticastSelector.build())
+                .withPriority(100)
+                .fromApp(srService.appId())
+                .makePermanent();
+        ObjectiveContext context = new DefaultObjectiveContext(
+                (objective) -> log.debug("L2 multicasting rule for device {}, port/vlan {}/{} deleted", deviceId,
+                                         pairPort, vlanId),
+                (objective, error) -> log.warn("Failed to delete L2 multicasting rule for device {}, " +
+                                                       "ports/vlan {}/{}: {}", deviceId, pairPort, vlanId, error));
+        flowObjectiveService.forward(deviceId, vlanMulticastForwardingObj.remove(context));
+
+        // Step 2 : Clear L2 multicast group associated with vlan
+        NextObjective.Builder l2MulticastGroupBuilder = DefaultNextObjective
+                .builder()
+                .withId(vlanMulticastNextId)
+                .withType(NextObjective.Type.BROADCAST)
+                .fromApp(srService.appId())
+            .withMeta(DefaultTrafficSelector.builder()
+                          .matchVlanId(vlanId)
+                          .matchEthDst(MacAddress.IPV4_MULTICAST).build())
+                .addTreatment(DefaultTrafficTreatment.builder().popVlan().setOutput(pairPort).build());
+        context = new DefaultObjectiveContext(
+                (objective) ->
+                        log.debug("L2 multicast group with NextObject Id {} deleted on {} for subnet {} ",
+                                  vlanMulticastNextId, deviceId, vlanId),
+                (objective, error) ->
+                        log.warn("L2 multicast group with NextObject Id {} failed to delete on {} for subnet {} : {}",
+                                 vlanMulticastNextId, deviceId, vlanId, error)
+        );
+        flowObjectiveService.next(deviceId, l2MulticastGroupBuilder.remove(context));
+
+        // Finally clear store.
+        removeMulticastGroup(deviceId, vlanId);
+    }
+
+    private boolean isMulticastGroupExists(DeviceId deviceId, VlanId vlanId) {
+        return xconnectMulticastNextStore.asJavaMap().entrySet().stream()
+                .anyMatch(e -> e.getKey().deviceId().equals(deviceId) &&
+                        e.getKey().vlanId().equals(vlanId));
+    }
+
+    private int getMulticastGroupNextObjectiveId(DeviceId deviceId, VlanId vlanId) {
+        Optional<Integer> nextId
+                = xconnectMulticastNextStore.asJavaMap().entrySet().stream()
+                .filter(e -> e.getKey().deviceId().equals(deviceId) &&
+                        e.getKey().vlanId().equals(vlanId))
+                .findFirst()
+                .map(Map.Entry::getValue);
+        return nextId.orElse(-1);
+    }
+
+    private void addMulticastGroupNextObjectiveId(DeviceId deviceId, VlanId vlanId, int nextId) {
+        if (nextId == -1) {
+            return;
+        }
+        VlanNextObjectiveStoreKey key = new VlanNextObjectiveStoreKey(deviceId, vlanId);
+        xconnectMulticastNextStore.put(key, nextId);
+
+        // Update port store with empty entry.
+        xconnectMulticastPortsStore.put(key, new ArrayList<PortNumber>());
+    }
+
+    private void addMulticastGroupPort(DeviceId deviceId, VlanId vlanId, PortNumber port) {
+        VlanNextObjectiveStoreKey key = new VlanNextObjectiveStoreKey(deviceId, vlanId);
+        List<PortNumber> ports = xconnectMulticastPortsStore.get(key).value();
+        ports.add(port);
+        xconnectMulticastPortsStore.put(key, ports);
+    }
+
+    private void removeMulticastGroupPort(DeviceId deviceId, VlanId vlanId, PortNumber port) {
+        VlanNextObjectiveStoreKey key = new VlanNextObjectiveStoreKey(deviceId, vlanId);
+        List<PortNumber> ports = xconnectMulticastPortsStore.get(key).value();
+        ports.remove(port);
+        xconnectMulticastPortsStore.put(key, ports);
+    }
+
+    private void removeMulticastGroup(DeviceId deviceId, VlanId vlanId) {
+        VlanNextObjectiveStoreKey key = new VlanNextObjectiveStoreKey(deviceId, vlanId);
+        xconnectMulticastPortsStore.remove(key);
+        xconnectMulticastNextStore.remove(key);
+    }
+
+    private boolean hasAccessPortInMulticastGroup(DeviceId deviceId, VlanId vlanId, PortNumber pairPort) {
+        VlanNextObjectiveStoreKey key = new VlanNextObjectiveStoreKey(deviceId, vlanId);
+        if (!xconnectMulticastPortsStore.containsKey(key)) {
+            return false;
+        }
+        List<PortNumber> ports = xconnectMulticastPortsStore.get(key).value();
+        return ports.stream().anyMatch(p -> !p.equals(pairPort));
+    }
+
 }
