diff --git a/app/src/main/java/org/opencord/olt/impl/Olt.java b/app/src/main/java/org/opencord/olt/impl/Olt.java
index 3775060..e392b41 100644
--- a/app/src/main/java/org/opencord/olt/impl/Olt.java
+++ b/app/src/main/java/org/opencord/olt/impl/Olt.java
@@ -16,15 +16,9 @@
 package org.opencord.olt.impl;
 
 import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
-import org.onlab.packet.EthType;
-import org.onlab.packet.IPv4;
-import org.onlab.packet.IPv6;
-import org.onlab.packet.TpPort;
 import org.onlab.packet.VlanId;
-import org.onlab.util.Tools;
 import org.onosproject.cfg.ComponentConfigService;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
@@ -39,43 +33,23 @@
 import org.onosproject.net.device.DeviceEvent;
 import org.onosproject.net.device.DeviceListener;
 import org.onosproject.net.device.DeviceService;
-import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
-import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.flow.criteria.Criteria;
-import org.onosproject.net.flowobjective.DefaultFilteringObjective;
-import org.onosproject.net.flowobjective.DefaultForwardingObjective;
-import org.onosproject.net.flowobjective.FilteringObjective;
 import org.onosproject.net.flowobjective.FlowObjectiveService;
 import org.onosproject.net.flowobjective.ForwardingObjective;
 import org.onosproject.net.flowobjective.Objective;
 import org.onosproject.net.flowobjective.ObjectiveContext;
 import org.onosproject.net.flowobjective.ObjectiveError;
-import org.onosproject.net.meter.Band;
-import org.onosproject.net.meter.DefaultBand;
-import org.onosproject.net.meter.DefaultMeterRequest;
-import org.onosproject.net.meter.Meter;
-import org.onosproject.net.meter.MeterContext;
-import org.onosproject.net.meter.MeterEvent;
-import org.onosproject.net.meter.MeterFailReason;
 import org.onosproject.net.meter.MeterId;
-import org.onosproject.net.meter.MeterKey;
-import org.onosproject.net.meter.MeterListener;
-import org.onosproject.net.meter.MeterRequest;
-import org.onosproject.net.meter.MeterService;
-import org.onosproject.store.serializers.KryoNamespaces;
-import org.onosproject.store.service.ConsistentMultimap;
-import org.onosproject.store.service.Serializer;
-import org.onosproject.store.service.StorageService;
 import org.opencord.olt.AccessDeviceEvent;
 import org.opencord.olt.AccessDeviceListener;
 import org.opencord.olt.AccessDeviceService;
 import org.opencord.olt.AccessSubscriberId;
+import org.opencord.olt.internalapi.AccessDeviceFlowService;
+import org.opencord.olt.internalapi.AccessDeviceMeterService;
 import org.opencord.sadis.BandwidthProfileInformation;
 import org.opencord.sadis.BaseInformationService;
 import org.opencord.sadis.SadisService;
 import org.opencord.sadis.SubscriberAndDeviceInformation;
+import org.opencord.sadis.UniTagInformation;
 import org.osgi.service.component.ComponentContext;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
@@ -85,10 +59,7 @@
 import org.osgi.service.component.annotations.ReferenceCardinality;
 import org.slf4j.Logger;
 
-import java.util.AbstractMap;
 import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
 import java.util.Dictionary;
 import java.util.List;
 import java.util.Map;
@@ -97,34 +68,15 @@
 import java.util.Properties;
 import java.util.Set;
 import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.stream.Collectors;
 
 import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Strings.isNullOrEmpty;
 import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
 import static org.onlab.util.Tools.get;
 import static org.onlab.util.Tools.groupedThreads;
-import static org.opencord.olt.impl.OsgiPropertyConstants.DEFAULT_BP_ID;
-import static org.opencord.olt.impl.OsgiPropertyConstants.DEFAULT_BP_ID_DEFAULT;
-import static org.opencord.olt.impl.OsgiPropertyConstants.DEFAULT_TP_ID;
-import static org.opencord.olt.impl.OsgiPropertyConstants.DEFAULT_TP_ID_DEFAULT;
-import static org.opencord.olt.impl.OsgiPropertyConstants.DEFAULT_VLAN;
-import static org.opencord.olt.impl.OsgiPropertyConstants.DEFAULT_VLAN_DEFAULT;
-import static org.opencord.olt.impl.OsgiPropertyConstants.DELETE_METERS;
-import static org.opencord.olt.impl.OsgiPropertyConstants.DELETE_METERS_DEFAULT;
-import static org.opencord.olt.impl.OsgiPropertyConstants.ENABLE_DHCP_ON_PROVISIONING;
-import static org.opencord.olt.impl.OsgiPropertyConstants.ENABLE_DHCP_ON_PROVISIONING_DEFAULT;
-import static org.opencord.olt.impl.OsgiPropertyConstants.ENABLE_DHCP_V4;
-import static org.opencord.olt.impl.OsgiPropertyConstants.ENABLE_DHCP_V4_DEFAULT;
-import static org.opencord.olt.impl.OsgiPropertyConstants.ENABLE_DHCP_V6;
-import static org.opencord.olt.impl.OsgiPropertyConstants.ENABLE_DHCP_V6_DEFAULT;
-import static org.opencord.olt.impl.OsgiPropertyConstants.ENABLE_EAPOL;
-import static org.opencord.olt.impl.OsgiPropertyConstants.ENABLE_EAPOL_DEFAULT;
-import static org.opencord.olt.impl.OsgiPropertyConstants.ENABLE_IGMP_ON_PROVISIONING;
-import static org.opencord.olt.impl.OsgiPropertyConstants.ENABLE_IGMP_ON_PROVISIONING_DEFAULT;
+import static org.opencord.olt.impl.OsgiPropertyConstants.*;
 import static org.slf4j.LoggerFactory.getLogger;
 
 /**
@@ -132,15 +84,8 @@
  */
 @Component(immediate = true,
         property = {
-                DEFAULT_VLAN + ":Integer=" + DEFAULT_VLAN_DEFAULT,
-                ENABLE_DHCP_ON_PROVISIONING + ":Boolean=" + ENABLE_DHCP_ON_PROVISIONING_DEFAULT,
-                ENABLE_DHCP_V4 + ":Boolean=" + ENABLE_DHCP_V4_DEFAULT,
-                ENABLE_DHCP_V6 + ":Boolean=" + ENABLE_DHCP_V6_DEFAULT,
-                ENABLE_IGMP_ON_PROVISIONING + ":Boolean=" + ENABLE_IGMP_ON_PROVISIONING_DEFAULT,
-                DELETE_METERS + ":Boolean=" + DELETE_METERS_DEFAULT,
-                DEFAULT_TP_ID + ":Integer=" + DEFAULT_TP_ID_DEFAULT,
                 DEFAULT_BP_ID + ":String=" + DEFAULT_BP_ID_DEFAULT,
-                ENABLE_EAPOL + ":Boolean=" + ENABLE_EAPOL_DEFAULT,
+                DEFAULT_MCAST_SERVICE_NAME + ":String=" + DEFAULT_MCAST_SERVICE_NAME_DEFAULT,
         })
 public class Olt
         extends AbstractListenerManager<AccessDeviceEvent, AccessDeviceListener>
@@ -148,12 +93,7 @@
     private static final String APP_NAME = "org.opencord.olt";
 
     private static final short EAPOL_DEFAULT_VLAN = 4091;
-    private static final String ADDITIONAL_VLANS = "additional-vlans";
     private static final String NO_UPLINK_PORT = "No uplink port found for OLT device {}";
-    private static final String INSTALLED = "installed";
-    private static final String REMOVED = "removed";
-    private static final String INSTALLATION = "installation";
-    private static final String REMOVAL = "removal";
 
     private final Logger log = getLogger(getClass());
 
@@ -176,45 +116,10 @@
     protected SadisService sadisService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    protected MeterService meterService;
+    protected AccessDeviceFlowService oltFlowService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    protected StorageService storageService;
-
-    /**
-     * Default VLAN RG<->ONU traffic.
-     **/
-    private int defaultVlan = DEFAULT_VLAN_DEFAULT;
-
-    /**
-     * Create the DHCP Flow rules when a subscriber is provisioned.
-     **/
-    protected boolean enableDhcpOnProvisioning = ENABLE_DHCP_ON_PROVISIONING_DEFAULT;
-
-    /**
-     * Enable flows for DHCP v4.
-     **/
-    protected boolean enableDhcpV4 = ENABLE_DHCP_V4_DEFAULT;
-
-    /**
-     * Enable flows for DHCP v6.
-     **/
-    protected boolean enableDhcpV6 = ENABLE_DHCP_V6_DEFAULT;
-
-    /**
-     * Create IGMP Flow rules when a subscriber is provisioned.
-     **/
-    protected boolean enableIgmpOnProvisioning = ENABLE_IGMP_ON_PROVISIONING_DEFAULT;
-
-    /**
-     * Deleting Meters based on flow count statistics.
-     **/
-    protected boolean deleteMeters = DELETE_METERS_DEFAULT;
-
-    /**
-     * Default technology profile id that is used for authentication trap flows.
-     **/
-    protected int defaultTechProfileId = DEFAULT_TP_ID_DEFAULT;
+    protected AccessDeviceMeterService oltMeterService;
 
     /**
      * Default bandwidth profile id that is used for authentication trap flows.
@@ -222,49 +127,41 @@
     protected String defaultBpId = DEFAULT_BP_ID_DEFAULT;
 
     /**
-     * Send EAPOL authentication trap flows before subscriber provisioning.
+     * Deleting Meters based on flow count statistics.
      **/
-    protected boolean enableEapol = ENABLE_EAPOL_DEFAULT;
+    protected String multicastServiceName = DEFAULT_MCAST_SERVICE_NAME;
 
     private final DeviceListener deviceListener = new InternalDeviceListener();
-    private final MeterListener meterListener = new InternalMeterListener();
 
-    private ApplicationId appId;
     protected BaseInformationService<SubscriberAndDeviceInformation> subsService;
     private BaseInformationService<BandwidthProfileInformation> bpService;
 
-    private Map<String, List<MeterKey>> bpInfoToMeter = new ConcurrentHashMap<>();
-
     private ExecutorService oltInstallers = Executors.newFixedThreadPool(4,
-            groupedThreads("onos/olt-service",
-                    "olt-installer-%d"));
-
-    private ConsistentMultimap<ConnectPoint, Map.Entry<VlanId, VlanId>> additionalVlans;
+                                                                         groupedThreads("onos/olt-service",
+                                                                                        "olt-installer-%d"));
 
     protected ExecutorService eventExecutor;
 
-    private Map<ConnectPoint, SubscriberAndDeviceInformation> programmedSubs;
-    private Set<MeterKey> programmedMeters;
-
+    private Map<ConnectPoint, Set<UniTagInformation>> programmedSubs;
 
     @Activate
     public void activate(ComponentContext context) {
-        eventExecutor = newSingleThreadScheduledExecutor(groupedThreads("onos/olt", "events-%d", log));
+        eventExecutor = newSingleThreadScheduledExecutor(groupedThreads("onos/olt",
+                                                                        "events-%d", log));
         modified(context);
-        appId = coreService.registerApplication(APP_NAME);
+        ApplicationId appId = coreService.registerApplication(APP_NAME);
 
         // ensure that flow rules are purged from flow-store upon olt-disconnection
         // when olt reconnects, the port-numbers may change for the ONUs
         // making flows pushed earlier invalid
         componentConfigService
                 .preSetProperty("org.onosproject.net.flow.impl.FlowRuleManager",
-                        "purgeOnDisconnection", "true");
+                                "purgeOnDisconnection", "true");
         componentConfigService
                 .preSetProperty("org.onosproject.net.meter.impl.MeterManager",
-                        "purgeOnDisconnection", "true");
+                                "purgeOnDisconnection", "true");
         componentConfigService.registerProperties(getClass());
         programmedSubs = Maps.newConcurrentMap();
-        programmedMeters = ConcurrentHashMap.newKeySet();
 
         eventDispatcher.addSink(AccessDeviceEvent.class, listenerRegistry);
 
@@ -278,15 +175,7 @@
             checkAndCreateDeviceFlows(d);
         }
 
-        additionalVlans = storageService.<ConnectPoint, Map.Entry<VlanId, VlanId>>consistentMultimapBuilder()
-                .withName(ADDITIONAL_VLANS)
-                .withSerializer(Serializer.using(Arrays.asList(KryoNamespaces.API),
-                        AbstractMap.SimpleEntry.class))
-                .build();
-
         deviceService.addListener(deviceListener);
-        meterService.addListener(meterListener);
-
         log.info("Started with Application ID {}", appId.id());
     }
 
@@ -294,7 +183,6 @@
     public void deactivate() {
         componentConfigService.unregisterProperties(getClass(), false);
         deviceService.removeListener(deviceListener);
-        meterService.removeListener(meterListener);
         eventDispatcher.removeSink(AccessDeviceEvent.class);
         log.info("Stopped");
     }
@@ -304,50 +192,16 @@
         Dictionary<?, ?> properties = context != null ? context.getProperties() : new Properties();
 
         try {
-            String s = get(properties, "defaultVlan");
-            defaultVlan = isNullOrEmpty(s) ? DEFAULT_VLAN_DEFAULT : Integer.parseInt(s.trim());
-
-            Boolean o = Tools.isPropertyEnabled(properties, "enableDhcpOnProvisioning");
-            if (o != null) {
-                enableDhcpOnProvisioning = o;
-            }
-
-            Boolean v4 = Tools.isPropertyEnabled(properties, "enableDhcpV4");
-            if (v4 != null) {
-                enableDhcpV4 = v4;
-            }
-
-            Boolean v6 = Tools.isPropertyEnabled(properties, "enableDhcpV6");
-            if (v6 != null) {
-                enableDhcpV6 = v6;
-            }
-
-            Boolean p = Tools.isPropertyEnabled(properties, "enableIgmpOnProvisioning");
-            if (p != null) {
-                enableIgmpOnProvisioning = p;
-            }
-
-            log.info("DHCP Settings [enableDhcpOnProvisioning: {}, enableDhcpV4: {}, enableDhcpV6: {}]",
-                    enableDhcpOnProvisioning, enableDhcpV4, enableDhcpV6);
-
-            Boolean d = Tools.isPropertyEnabled(properties, "deleteMeters");
-            if (d != null) {
-                deleteMeters = d;
-            }
-
-            String tpId = get(properties, "defaultTechProfileId");
-            defaultTechProfileId = isNullOrEmpty(s) ? DEFAULT_TP_ID_DEFAULT : Integer.parseInt(tpId.trim());
-
             String bpId = get(properties, "defaultBpId");
             defaultBpId = bpId;
 
-            Boolean eap = Tools.isPropertyEnabled(properties, "enableEapol");
-            if (eap != null) {
-                enableEapol = eap;
-            }
+            String mcastSN = get(properties, "multicastServiceName");
+            multicastServiceName = mcastSN;
+
+            log.debug("OLT properties: DefaultBpId: {}, MulticastServiceName: {}", defaultBpId, multicastServiceName);
 
         } catch (Exception e) {
-            defaultVlan = DEFAULT_VLAN_DEFAULT;
+            log.error("Error while modifying the properties", e);
         }
     }
 
@@ -358,15 +212,7 @@
         PortNumber subscriberPortNo = connectPoint.port();
 
         checkNotNull(deviceService.getPort(deviceId, subscriberPortNo),
-                "Invalid connect point");
-
-        // If the subscriber is modified then first remove the previous and proceed
-        SubscriberAndDeviceInformation subscriber = programmedSubs.get(connectPoint);
-        if (subscriber != null) {
-            log.info("Subscriber on connectionPoint {} was previously programmed, " +
-                    "remove it before adding again", connectPoint);
-            removeSubscriber(connectPoint);
-        }
+                     "Invalid connect point:" + connectPoint);
 
         // Find the subscriber on this connect point
         SubscriberAndDeviceInformation sub = getSubscriber(connectPoint);
@@ -382,37 +228,17 @@
             return false;
         }
 
-        SubscriberAndDeviceInformation prgSub = programmedSubs.get(connectPoint);
-        if (prgSub != null) {
-            log.warn("Subscriber {} on connectionPoint {} was previously programmed .. "
-                    + "taking no action. Note that updating a subscribers params "
-                    + "(vlans, bw, tpid etc) requires removing the subscriber"
-                    + "before re-provisioning the subscriber", prgSub.id(),
-                     connectPoint);
-            return true;
-        }
-
         //delete Eapol authentication flow with default bandwidth
         //wait until Eapol rule with defaultBpId is removed to install subscriber-based rules
-        CompletableFuture<ObjectiveError> filterFuture = new CompletableFuture();
-        processEapolFilteringObjectives(deviceId, subscriberPortNo, defaultBpId, filterFuture,
-                VlanId.vlanId(EAPOL_DEFAULT_VLAN), false);
-        // do not remove meter from bpInfoToMeter mapping as flows for other ONUs
-        // could still be using it - this also prevents duplicate meters from being
-        // created for the same bandwidth profile
-        // we still need to remove from programmedMeters so the meter can be
-        // deleted if its reference count drops to zero
-        removeMeterIdFromPrgMeters(deviceId, defaultBpId);
-
         //install subscriber flows
+        CompletableFuture<ObjectiveError> filterFuture = new CompletableFuture();
+        oltFlowService.processEapolFilteringObjectives(deviceId, subscriberPortNo, defaultBpId, filterFuture,
+                                                       VlanId.vlanId(EAPOL_DEFAULT_VLAN), false);
         filterFuture.thenAcceptAsync(filterStatus -> {
             if (filterStatus == null) {
-                provisionSubscriberBasedFlows(connectPoint, uplinkPort.number(), Optional.empty(), sub);
+                provisionUniTagList(connectPoint, uplinkPort.number(), sub);
             }
         });
-
-        // cache subscriber info
-        programmedSubs.put(connectPoint, sub);
         return true;
     }
 
@@ -425,10 +251,10 @@
         DeviceId deviceId = connectPoint.deviceId();
         PortNumber subscriberPortNo = connectPoint.port();
 
-        SubscriberAndDeviceInformation subscriber = programmedSubs.get(connectPoint);
-        if (subscriber == null) {
+        Set<UniTagInformation> uniTagInformationSet = programmedSubs.get(connectPoint);
+        if (uniTagInformationSet == null || uniTagInformationSet.isEmpty()) {
             log.warn("Subscriber on connectionPoint {} was not previously programmed, " +
-                    "no need to remove it", connectPoint);
+                             "no need to remove it", connectPoint);
             return true;
         }
 
@@ -439,53 +265,38 @@
             return false;
         }
 
-        //delete dhcp & igmp trap flows
-        MeterId upstreamMeterId = getMeterIdFromBpMapping(deviceId, subscriber.upstreamBandwidthProfile());
+        for (UniTagInformation uniTag : uniTagInformationSet) {
 
-        // remove dhcp filters
-        processDhcpFilteringObjectives(deviceId, subscriberPortNo,
-                upstreamMeterId, subscriber.technologyProfileId(), false, true);
+            if (multicastServiceName.equals(uniTag.getServiceName())) {
+                continue;
+            }
 
-        // remove igmp filters
-        processIgmpFilteringObjectives(deviceId, subscriberPortNo,
-                upstreamMeterId, subscriber.technologyProfileId(), false);
+            unprovisionVlans(deviceId, uplinkPort.number(), subscriberPortNo, uniTag);
 
-        //unprovision vlans
-        unprovisionVlans(deviceId, uplinkPort.number(), subscriberPortNo, subscriber, Optional.empty());
+            // re-install eapol with default bandwidth profile
+            oltFlowService.processEapolFilteringObjectives(deviceId, subscriberPortNo,
+                                                           uniTag.getUpstreamBandwidthProfile(),
+                                                           null, uniTag.getPonCTag(), false);
 
-        // Remove if there are any flows for the additional Vlans
-        Collection<? extends Map.Entry<VlanId, VlanId>> vlansList = additionalVlans.get(connectPoint).value();
-
-        // Remove the flows for the additional vlans for this subscriber
-        for (Map.Entry<VlanId, VlanId> vlans : vlansList) {
-            unprovisionTransparentFlows(deviceId, uplinkPort.number(), subscriberPortNo,
-                    vlans.getValue(), vlans.getKey());
-
-            // Remove it from the map also
-            additionalVlans.remove(connectPoint, vlans);
+            Port port = deviceService.getPort(deviceId, subscriberPortNo);
+            if (port != null && port.isEnabled()) {
+                oltFlowService.processEapolFilteringObjectives(deviceId, subscriberPortNo, defaultBpId,
+                                                               null, VlanId.vlanId(EAPOL_DEFAULT_VLAN), true);
+            } else {
+                log.debug("Port {} is no longer enabled or it's unavailable. Not "
+                                  + "reprogramming default eapol flow", connectPoint);
+            }
         }
-
-        // re-install eapol with default bandwidth profile
-        processEapolFilteringObjectives(deviceId, subscriberPortNo,
-                subscriber.upstreamBandwidthProfile(), null, subscriber.cTag(), false);
-
-        Port port = deviceService.getPort(deviceId, subscriberPortNo);
-        if (port != null && port.isEnabled()) {
-            processEapolFilteringObjectives(deviceId, subscriberPortNo, defaultBpId,
-                    null, VlanId.vlanId(EAPOL_DEFAULT_VLAN), true);
-        } else {
-            log.debug("Port {} is no longer enabled or it's unavailable. Not "
-                    + "reprogramming default eapol flow", connectPoint);
-        }
-
-        programmedSubs.remove(connectPoint);
         return true;
     }
 
-    @Override
-    public boolean provisionSubscriber(AccessSubscriberId subscriberId, Optional<VlanId> sTag, Optional<VlanId> cTag) {
 
-        log.info("Provisioning subscriber using subscriberId {}, sTag {}, cTag {}", subscriberId, sTag, cTag);
+    @Override
+    public boolean provisionSubscriber(AccessSubscriberId subscriberId, Optional<VlanId> sTag,
+                                       Optional<VlanId> cTag, Optional<Integer> tpId) {
+
+        log.info("Provisioning subscriber using subscriberId {}, sTag {}, cTag {}, tpId {}" +
+                         "", subscriberId, sTag, cTag, tpId);
 
         // Check if we can find the connect point to which this subscriber is connected
         ConnectPoint subsPort = findSubscriberConnectPoint(subscriberId.toString());
@@ -496,31 +307,23 @@
 
         if (!sTag.isPresent() && !cTag.isPresent()) {
             return provisionSubscriber(subsPort);
-        } else if (sTag.isPresent() && cTag.isPresent()) {
+        } else if (sTag.isPresent() && cTag.isPresent() && tpId.isPresent()) {
             Port uplinkPort = getUplinkPort(deviceService.getDevice(subsPort.deviceId()));
             if (uplinkPort == null) {
                 log.warn(NO_UPLINK_PORT, subsPort.deviceId());
                 return false;
             }
 
-            CompletableFuture<ObjectiveError> filterFuture = new CompletableFuture();
-
             //delete Eapol authentication flow with default bandwidth
             //wait until Eapol rule with defaultBpId is removed to install subscriber-based rules
-            processEapolFilteringObjectives(subsPort.deviceId(), subsPort.port(), defaultBpId, filterFuture,
-                    VlanId.vlanId(EAPOL_DEFAULT_VLAN), false);
-            // do not remove meter from bpInfoToMeter mapping as flows for other ONUs
-            // could still be using it - this also prevents duplicate meters from being
-            // created for the same bandwidth profile
-            // we still need to remove from programmedMeters so the meter can be
-            // deleted if its reference count drops to zero
-            removeMeterIdFromPrgMeters(subsPort.deviceId(), defaultBpId);
-
             //install subscriber flows
+            CompletableFuture<ObjectiveError> filterFuture = new CompletableFuture();
+            oltFlowService.processEapolFilteringObjectives(subsPort.deviceId(), subsPort.port(), defaultBpId,
+                                                           filterFuture, VlanId.vlanId(EAPOL_DEFAULT_VLAN), false);
             filterFuture.thenAcceptAsync(filterStatus -> {
                 if (filterStatus == null) {
-                    provisionTransparentFlows(subsPort.deviceId(), uplinkPort.number(), subsPort.port(),
-                            cTag.get(), sTag.get());
+                    provisionUniTagInformation(subsPort.deviceId(), uplinkPort.number(), subsPort.port(),
+                                               cTag.get(), sTag.get(), tpId.get());
                 }
             });
             return true;
@@ -531,7 +334,8 @@
     }
 
     @Override
-    public boolean removeSubscriber(AccessSubscriberId subscriberId, Optional<VlanId> sTag, Optional<VlanId> cTag) {
+    public boolean removeSubscriber(AccessSubscriberId subscriberId, Optional<VlanId> sTag,
+                                    Optional<VlanId> cTag, Optional<Integer> tpId) {
         // Check if we can find the connect point to which this subscriber is connected
         ConnectPoint subsPort = findSubscriberConnectPoint(subscriberId.toString());
         if (subsPort == null) {
@@ -541,7 +345,7 @@
 
         if (!sTag.isPresent() && !cTag.isPresent()) {
             return removeSubscriber(subsPort);
-        } else if (sTag.isPresent() && cTag.isPresent()) {
+        } else if (sTag.isPresent() && cTag.isPresent() && tpId.isPresent()) {
             // Get the uplink port
             Port uplinkPort = getUplinkPort(deviceService.getDevice(subsPort.deviceId()));
             if (uplinkPort == null) {
@@ -549,60 +353,28 @@
                 return false;
             }
 
-            unprovisionTransparentFlows(subsPort.deviceId(), uplinkPort.number(), subsPort.port(),
-                    cTag.get(), sTag.get());
+            Optional<UniTagInformation> tagInfo = getUniTagInformation(subsPort, cTag.get(), sTag.get(), tpId.get());
+            if (!tagInfo.isPresent()) {
+                log.warn("UniTagInformation does not exist for Device/Port {}, cTag {}, sTag {}, tpId {}",
+                         subsPort, cTag, sTag, tpId);
+                return false;
+            }
 
-            programmedSubs.remove(subsPort);
-
+            unprovisionVlans(subsPort.deviceId(), uplinkPort.number(), subsPort.port(), tagInfo.get());
             return true;
         } else {
-            log.warn("Removing subscriber failed for: {}", subscriberId);
+            log.warn("Removing subscriber is not possible - please check the provided information" +
+                             "for the subscriber: {}", subscriberId);
             return false;
         }
     }
 
     @Override
-    public Collection<Map.Entry<ConnectPoint, Map.Entry<VlanId, VlanId>>> getSubscribers() {
-        ArrayList<Map.Entry<ConnectPoint, Map.Entry<VlanId, VlanId>>> subs = new ArrayList<>();
-
-        // Get the subscribers for all the devices configured in sadis
-        // If the port is UNI, is enabled and exists in Sadis then copy it
-        for (Device d : deviceService.getDevices()) {
-            if (getOltInfo(d) == null) {
-                continue; // not an olt, or not configured in sadis
-            }
-            for (Port p : deviceService.getPorts(d.id())) {
-                if (isUniPort(d, p) && p.isEnabled()) {
-                    ConnectPoint cp = new ConnectPoint(d.id(), p.number());
-
-                    SubscriberAndDeviceInformation sub = getSubscriber(cp);
-                    if (sub != null) {
-                        Map.Entry<VlanId, VlanId> vlans = new AbstractMap.SimpleEntry(sub.sTag(), sub.cTag());
-                        subs.add(new AbstractMap.SimpleEntry(cp, vlans));
-                    }
-                }
-            }
-        }
-
-        return subs;
-    }
-
-    @Override
-    public ImmutableMap<ConnectPoint, SubscriberAndDeviceInformation> getProgSubs() {
+    public ImmutableMap<ConnectPoint, Set<UniTagInformation>> getProgSubs() {
         return ImmutableMap.copyOf(programmedSubs);
     }
 
     @Override
-    public ImmutableSet<MeterKey> getProgMeters() {
-        return ImmutableSet.copyOf(programmedMeters);
-    }
-
-    @Override
-    public ImmutableMap<String, List<MeterKey>> getBpMeterMappings() {
-        return ImmutableMap.copyOf(bpInfoToMeter);
-    }
-
-    @Override
     public List<DeviceId> fetchOlts() {
         // look through all the devices and find the ones that are OLTs as per Sadis
         List<DeviceId> olts = new ArrayList<>();
@@ -637,6 +409,12 @@
         return null;
     }
 
+    /**
+     * Gets the context of the bandwidth profile information for the given parameter.
+     *
+     * @param bandwidthProfile the bandwidth profile id
+     * @return the context of the bandwidth profile information
+     */
     private BandwidthProfileInformation getBandwidthProfileInformation(String bandwidthProfile) {
         if (bandwidthProfile == null) {
             return null;
@@ -650,30 +428,37 @@
      * @param deviceId       the device identifier
      * @param uplink         uplink port of the OLT
      * @param subscriberPort uni port
-     * @param subscriber     subscriber info that includes s, c tags, tech profile and bandwidth profile references
-     * @param defaultVlan    default vlan of the subscriber
+     * @param uniTag         uni tag information
      */
     private void unprovisionVlans(DeviceId deviceId, PortNumber uplink,
-                                  PortNumber subscriberPort, SubscriberAndDeviceInformation subscriber,
-                                  Optional<VlanId> defaultVlan) {
-        log.info("Unprovisioning vlans for subscriber {} on dev/port: {}/{}",
-                 subscriber, deviceId, subscriberPort);
+                                  PortNumber subscriberPort, UniTagInformation uniTag) {
+
+        log.info("Unprovisioning vlans for {} at {}/{}", uniTag, deviceId, subscriberPort);
 
         CompletableFuture<ObjectiveError> downFuture = new CompletableFuture();
         CompletableFuture<ObjectiveError> upFuture = new CompletableFuture();
 
-        VlanId deviceVlan = subscriber.sTag();
-        VlanId subscriberVlan = subscriber.cTag();
+        VlanId deviceVlan = uniTag.getPonSTag();
+        VlanId subscriberVlan = uniTag.getPonCTag();
 
-        MeterId upstreamMeterId = getMeterIdFromBpMapping(deviceId, subscriber.upstreamBandwidthProfile());
-        MeterId downstreamMeterId = getMeterIdFromBpMapping(deviceId, subscriber.downstreamBandwidthProfile());
+        MeterId upstreamMeterId = oltMeterService
+                .getMeterIdFromBpMapping(deviceId, uniTag.getUpstreamBandwidthProfile());
+        MeterId downstreamMeterId = oltMeterService
+                .getMeterIdFromBpMapping(deviceId, uniTag.getDownstreamBandwidthProfile());
 
-        ForwardingObjective.Builder upFwd = upBuilder(uplink, subscriberPort,
-                subscriberVlan, deviceVlan,
-                defaultVlan, upstreamMeterId, subscriber.technologyProfileId());
-        ForwardingObjective.Builder downFwd = downBuilder(uplink, subscriberPort,
-                subscriberVlan, deviceVlan,
-                defaultVlan, downstreamMeterId, subscriber.technologyProfileId());
+        ForwardingObjective.Builder upFwd =
+                oltFlowService.createUpBuilder(uplink, subscriberPort, upstreamMeterId, uniTag);
+        ForwardingObjective.Builder downFwd =
+                oltFlowService.createDownBuilder(uplink, subscriberPort, downstreamMeterId, uniTag);
+
+        if (uniTag.getIsIgmpRequired()) {
+            oltFlowService.processIgmpFilteringObjectives(deviceId, subscriberPort,
+                                                          upstreamMeterId, uniTag, false, true);
+        }
+        if (uniTag.getIsDhcpRequired()) {
+            oltFlowService.processDhcpFilteringObjectives(deviceId, subscriberPort,
+                                                          upstreamMeterId, uniTag, false, true);
+        }
 
         flowObjectiveService.forward(deviceId, upFwd.remove(new ObjectiveContext() {
             @Override
@@ -700,317 +485,148 @@
         }));
 
         upFuture.thenAcceptBothAsync(downFuture, (upStatus, downStatus) -> {
+            AccessDeviceEvent.Type type = AccessDeviceEvent.Type.SUBSCRIBER_UNI_TAG_UNREGISTERED;
             if (upStatus == null && downStatus == null) {
-                post(new AccessDeviceEvent(AccessDeviceEvent.Type.SUBSCRIBER_UNREGISTERED,
-                        deviceId,
-                        deviceVlan,
-                        subscriberVlan));
+                log.debug("Uni tag information is unregistered successfully for cTag {}, sTag {}, tpId {}, and" +
+                                  "Device/Port{}", uniTag.getPonCTag(), uniTag.getPonSTag(),
+                          uniTag.getTechnologyProfileId(), subscriberPort);
+                updateProgrammedSubscriber(new ConnectPoint(deviceId, subscriberPort), uniTag, false);
             } else if (downStatus != null) {
                 log.error("Subscriber with vlan {} on device {} " +
-                                "on port {} failed downstream uninstallation: {}",
-                        subscriberVlan, deviceId, subscriberPort, downStatus);
+                                  "on port {} failed downstream uninstallation: {}",
+                          subscriberVlan, deviceId, subscriberPort, downStatus);
+                type = AccessDeviceEvent.Type.SUBSCRIBER_UNI_TAG_UNREGISTRATION_FAILED;
             } else if (upStatus != null) {
                 log.error("Subscriber with vlan {} on device {} " +
-                                "on port {} failed upstream uninstallation: {}",
-                        subscriberVlan, deviceId, subscriberPort, upStatus);
+                                  "on port {} failed upstream uninstallation: {}",
+                          subscriberVlan, deviceId, subscriberPort, upStatus);
+                type = AccessDeviceEvent.Type.SUBSCRIBER_UNI_TAG_UNREGISTRATION_FAILED;
             }
+            Port port = deviceService.getPort(deviceId, subscriberPort);
+            post(new AccessDeviceEvent(type, deviceId, port, deviceVlan, subscriberVlan,
+                                       uniTag.getTechnologyProfileId()));
         }, oltInstallers);
-
-        programmedMeters.remove(MeterKey.key(deviceId, upstreamMeterId));
-        programmedMeters.remove(MeterKey.key(deviceId, downstreamMeterId));
-        log.debug("programmed Meters size {}", programmedMeters.size());
     }
 
     /**
      * Adds subscriber vlan flows, dhcp, eapol and igmp trap flows for the related uni port.
      *
-     * @param port        the connection point of the subscriber
-     * @param uplinkPort  uplink port of the OLT
-     * @param defaultVlan default vlan of the subscriber
-     * @param sub         subscriber information that includes s, c tags, tech profile and bandwidth profile references
+     * @param connectPoint the connection point of the subscriber
+     * @param uplinkPort   uplink port of the OLT (the nni port)
+     * @param sub          subscriber information that includes s, c tags, tech profile and bandwidth profile references
      */
-    private void provisionSubscriberBasedFlows(ConnectPoint port, PortNumber uplinkPort,
-                                               Optional<VlanId> defaultVlan,
-                                               SubscriberAndDeviceInformation sub) {
+    private void provisionUniTagList(ConnectPoint connectPoint, PortNumber uplinkPort,
+                                     SubscriberAndDeviceInformation sub) {
 
-        log.info("Provisioning vlans for subscriber {} on dev/port: {}",
-                 sub, port);
+        log.info("Provisioning vlans for subscriber {} on dev/port: {}", sub, connectPoint);
 
-        DeviceId deviceId = port.deviceId();
-        PortNumber subscriberPort = port.port();
-        VlanId deviceVlan = sub.sTag();
-        VlanId subscriberVlan = sub.cTag();
-        int techProfId = sub.technologyProfileId();
+        if (sub.uniTagList() == null || sub.uniTagList().isEmpty()) {
+            log.warn("Unitaglist doesn't exist for the subscriber {}", sub.id());
+            return;
+        }
 
-        BandwidthProfileInformation upstreamBpInfo = getBandwidthProfileInformation(sub.upstreamBandwidthProfile());
-        BandwidthProfileInformation downstreamBpInfo = getBandwidthProfileInformation(sub.downstreamBandwidthProfile());
+        DeviceId deviceId = connectPoint.deviceId();
+        PortNumber subscriberPort = connectPoint.port();
 
-        CompletableFuture<ObjectiveError> downFuture = new CompletableFuture();
-        CompletableFuture<ObjectiveError> upFuture = new CompletableFuture();
-        CompletableFuture<Object> upstreamMeterFuture = new CompletableFuture<>();
-        CompletableFuture<Object> downsteamMeterFuture = new CompletableFuture<>();
+        for (UniTagInformation uniTag : sub.uniTagList()) {
+            handleSubscriberFlows(deviceId, uplinkPort, subscriberPort, uniTag);
+        }
+    }
 
-        MeterId upstreamMeterId = createMeter(deviceId, upstreamBpInfo, upstreamMeterFuture);
-        MeterId downstreamMeterId = createMeter(deviceId, downstreamBpInfo, downsteamMeterFuture);
+    /**
+     * Finds the uni tag information and provisions the found information.
+     * If the uni tag information is not found, returns
+     *
+     * @param deviceId       the access device id
+     * @param uplinkPort     the nni port
+     * @param subscriberPort the uni port
+     * @param innerVlan      the pon c tag
+     * @param outerVlan      the pon s tag
+     * @param tpId           the technology profile id
+     */
+    private void provisionUniTagInformation(DeviceId deviceId, PortNumber uplinkPort,
+                                            PortNumber subscriberPort,
+                                            VlanId innerVlan,
+                                            VlanId outerVlan,
+                                            Integer tpId) {
 
-        //install upstream flows
-        upstreamMeterFuture.thenAcceptAsync(result -> {
-            if (result == null) {
-                log.info("Upstream Meter {} is in the device {}. " +
-                        "Sending subscriber flows.", upstreamMeterId, deviceId);
-                ForwardingObjective.Builder upFwd = upBuilder(uplinkPort, subscriberPort,
-                        subscriberVlan, deviceVlan,
-                        defaultVlan, upstreamMeterId, techProfId);
+        ConnectPoint cp = new ConnectPoint(deviceId, subscriberPort);
+        Optional<UniTagInformation> gotTagInformation = getUniTagInformation(cp, innerVlan, outerVlan, tpId);
+        if (!gotTagInformation.isPresent()) {
+            return;
+        }
+        UniTagInformation tagInformation = gotTagInformation.get();
+        handleSubscriberFlows(deviceId, uplinkPort, subscriberPort, tagInformation);
+    }
 
-
-                flowObjectiveService.forward(deviceId, upFwd.add(new ObjectiveContext() {
-                    @Override
-                    public void onSuccess(Objective objective) {
-                        upFuture.complete(null);
-                    }
-
-                    @Override
-                    public void onError(Objective objective, ObjectiveError error) {
-                        upFuture.complete(error);
-                    }
-                }));
-            } else {
-                log.warn("Meter installation error while sending upstream flows. " +
-                        "Result {} and MeterId {}", result, upstreamMeterId);
-            }
-        });
-
-        //install downstream flows
-        downsteamMeterFuture.thenAcceptAsync(result -> {
-            if (result == null) {
-                log.info("Downstream Meter {} is in the device {}. " +
-                        "Sending subscriber flows.", downstreamMeterId, deviceId);
-                ForwardingObjective.Builder downFwd = downBuilder(uplinkPort, subscriberPort,
-                        subscriberVlan, deviceVlan,
-                        defaultVlan, downstreamMeterId, techProfId);
-
-                flowObjectiveService.forward(deviceId, downFwd.add(new ObjectiveContext() {
-                    @Override
-                    public void onSuccess(Objective objective) {
-                        downFuture.complete(null);
-                    }
-
-                    @Override
-                    public void onError(Objective objective, ObjectiveError error) {
-                        downFuture.complete(error);
-                    }
-                }));
-            } else {
-                log.warn("Meter installation error while sending downstream flows. " +
-                        "Result {} and MeterId {}", result, downstreamMeterId);
-            }
-        });
-
-        //send eapol & dhcp & igmp flows
-        //send Subscriber Registered event
-        upFuture.thenAcceptBothAsync(downFuture, (upStatus, downStatus) -> {
-            if (upStatus == null && downStatus == null) {
-
-                if (upstreamMeterId != null) {
-                    //re-install Eapol authentication flow with the subscribers' upstream bandwidth profile
-                    processEapolFilteringObjectives(deviceId, subscriberPort, sub.upstreamBandwidthProfile(),
-                            null, sub.cTag(), true);
-
-                    processDhcpFilteringObjectives(deviceId, subscriberPort,
-                            upstreamMeterId, sub.technologyProfileId(), true, true);
-
-                    processIgmpFilteringObjectives(deviceId, subscriberPort,
-                            upstreamMeterId, sub.technologyProfileId(), true);
+    private void updateProgrammedSubscriber(ConnectPoint connectPoint, UniTagInformation tagInformation, Boolean add) {
+        programmedSubs.compute(connectPoint, (k, v) -> {
+            if (add) {
+                if (v == null) {
+                    v = Sets.newHashSet();
                 }
-
-                post(new AccessDeviceEvent(AccessDeviceEvent.Type.SUBSCRIBER_REGISTERED,
-                        deviceId,
-                        deviceVlan,
-                        subscriberVlan));
-
-            } else if (downStatus != null) {
-                log.error("Subscriber with vlan {} on device {} " +
-                                "on port {} failed downstream installation: {}",
-                        subscriberVlan, deviceId, subscriberPort, downStatus);
-            } else if (upStatus != null) {
-                log.error("Subscriber with vlan {} on device {} " +
-                                "on port {} failed upstream installation: {}",
-                        subscriberVlan, deviceId, subscriberPort, upStatus);
+                v.add(tagInformation);
+            } else {
+                if (v != null) {
+                    v.remove(tagInformation);
+                }
             }
-        }, oltInstallers);
+            return v;
+        });
     }
 
-    private MeterId createMeter(DeviceId deviceId, BandwidthProfileInformation bpInfo,
-                                CompletableFuture<Object> meterFuture) {
-        if (bpInfo == null) {
-            log.warn("Bandwidth profile information cannot be null when creating meter");
-            return null;
+    /**
+     * Installs a uni tag information flow.
+     *
+     * @param deviceId       the access device id
+     * @param uplinkPort     the nni port
+     * @param subscriberPort the uni port
+     * @param tagInfo        the uni tag information
+     */
+    private void handleSubscriberFlows(DeviceId deviceId, PortNumber uplinkPort, PortNumber subscriberPort,
+                                       UniTagInformation tagInfo) {
+
+        log.info("Provisioning vlan-based flows for the uniTagInformation {}", tagInfo);
+
+        Port port = deviceService.getPort(deviceId, subscriberPort);
+
+        if (multicastServiceName.equals(tagInfo.getServiceName())) {
+            // IGMP flows are taken care of along with VOD service
+            // Please note that for each service, Subscriber Registered event will be sent
+            post(new AccessDeviceEvent(AccessDeviceEvent.Type.SUBSCRIBER_UNI_TAG_REGISTERED,
+                                       deviceId, port, tagInfo.getPonSTag(), tagInfo.getPonCTag(),
+                                       tagInfo.getTechnologyProfileId()));
+            return;
         }
 
-        MeterId meterId = getMeterIdFromBpMapping(deviceId, bpInfo.id());
-        if (meterId != null) {
-            log.debug("Meter {} was previously created for bp {}", meterId,
-                     bpInfo.id());
-            meterFuture.complete(null);
-            return meterId;
-        }
-
-        List<Band> meterBands = createMeterBands(bpInfo);
-
-        MeterRequest meterRequest = DefaultMeterRequest.builder()
-                .withBands(meterBands)
-                .withUnit(Meter.Unit.KB_PER_SEC)
-                .withContext(new MeterContext() {
-                    @Override
-                    public void onSuccess(MeterRequest op) {
-                        log.debug("meter addition confirmed for bpInfo:{}", bpInfo);
-                        meterFuture.complete(null);
-                    }
-
-                    @Override
-                    public void onError(MeterRequest op, MeterFailReason reason) {
-                        meterFuture.complete(reason);
-                    }
-                })
-                .forDevice(deviceId)
-                .fromApp(appId)
-                .burst()
-                .add();
-
-        Meter meter = meterService.submit(meterRequest);
-        addMeterIdToBpMapping(deviceId, meter.id(), bpInfo.id());
-        log.info("Meter creation message sent for Meter Id {}", meter.id());
-        programmedMeters.add(MeterKey.key(deviceId, meter.id()));
-        return meter.id();
-    }
-
-    private List<Band> createMeterBands(BandwidthProfileInformation bpInfo) {
-        List<Band> meterBands = new ArrayList<>();
-
-        meterBands.add(createMeterBand(bpInfo.committedInformationRate(), bpInfo.committedBurstSize()));
-        meterBands.add(createMeterBand(bpInfo.exceededInformationRate(), bpInfo.exceededBurstSize()));
-        meterBands.add(createMeterBand(bpInfo.assuredInformationRate(), 0L));
-
-        return meterBands;
-    }
-
-    private Band createMeterBand(long rate, Long burst) {
-        return DefaultBand.builder()
-                .withRate(rate) //already Kbps
-                .burstSize(burst) // already Kbits
-                .ofType(Band.Type.DROP) // no matter
-                .build();
-    }
-
-    private ForwardingObjective.Builder downBuilder(PortNumber uplinkPort,
-                                                    PortNumber subscriberPort,
-                                                    VlanId subscriberVlan,
-                                                    VlanId deviceVlan,
-                                                    Optional<VlanId> defaultVlan,
-                                                    MeterId meterId,
-                                                    int techProfId) {
-        TrafficSelector downstream = DefaultTrafficSelector.builder()
-                .matchVlanId(deviceVlan)
-                .matchInPort(uplinkPort)
-                .matchInnerVlanId(subscriberVlan)
-                .build();
-
-        TrafficTreatment.Builder downstreamTreatmentBuilder = DefaultTrafficTreatment.builder()
-                .popVlan()
-                .setVlanId(defaultVlan.orElse(VlanId.vlanId((short) this.defaultVlan)))
-                .setOutput(subscriberPort);
-
-        if (meterId != null) {
-            downstreamTreatmentBuilder.meter(meterId);
-        }
-
-        downstreamTreatmentBuilder.writeMetadata(createMetadata(subscriberVlan, techProfId, subscriberPort), 0);
-
-        return DefaultForwardingObjective.builder()
-                .withFlag(ForwardingObjective.Flag.VERSATILE)
-                .withPriority(1000)
-                .makePermanent()
-                .withSelector(downstream)
-                .fromApp(appId)
-                .withTreatment(downstreamTreatmentBuilder.build());
-    }
-
-    private ForwardingObjective.Builder upBuilder(PortNumber uplinkPort,
-                                                  PortNumber subscriberPort,
-                                                  VlanId subscriberVlan,
-                                                  VlanId deviceVlan,
-                                                  Optional<VlanId> defaultVlan,
-                                                  MeterId meterId,
-                                                  int technologyProfileId) {
-
-
-        VlanId dVlan = defaultVlan.orElse(VlanId.vlanId((short) this.defaultVlan));
-
-        if (subscriberVlan.toShort() == 4096) {
-            dVlan = subscriberVlan;
-        }
-
-        TrafficSelector upstream = DefaultTrafficSelector.builder()
-                .matchVlanId(dVlan)
-                .matchInPort(subscriberPort)
-                .build();
-
-
-        TrafficTreatment.Builder upstreamTreatmentBuilder = DefaultTrafficTreatment.builder()
-                .pushVlan()
-                .setVlanId(subscriberVlan)
-                .pushVlan()
-                .setVlanId(deviceVlan)
-                .setOutput(uplinkPort);
-
-        if (meterId != null) {
-            upstreamTreatmentBuilder.meter(meterId);
-        }
-
-        upstreamTreatmentBuilder.writeMetadata(createMetadata(deviceVlan, technologyProfileId, uplinkPort), 0L);
-
-        return DefaultForwardingObjective.builder()
-                .withFlag(ForwardingObjective.Flag.VERSATILE)
-                .withPriority(1000)
-                .makePermanent()
-                .withSelector(upstream)
-                .fromApp(appId)
-                .withTreatment(upstreamTreatmentBuilder.build());
-    }
-
-    private void provisionTransparentFlows(DeviceId deviceId, PortNumber uplinkPort,
-                                           PortNumber subscriberPort,
-                                           VlanId innerVlan,
-                                           VlanId outerVlan) {
-
         ConnectPoint cp = new ConnectPoint(deviceId, subscriberPort);
 
-        SubscriberAndDeviceInformation subInfo = getSubscriber(cp);
-
-        BandwidthProfileInformation upstreamBpInfo = getBandwidthProfileInformation(
-                subInfo.upstreamBandwidthProfile());
-        BandwidthProfileInformation downstreamBpInfo = getBandwidthProfileInformation(
-                subInfo.downstreamBandwidthProfile());
+        BandwidthProfileInformation upstreamBpInfo =
+                getBandwidthProfileInformation(tagInfo.getUpstreamBandwidthProfile());
+        BandwidthProfileInformation downstreamBpInfo =
+                getBandwidthProfileInformation(tagInfo.getDownstreamBandwidthProfile());
 
         CompletableFuture<Object> upstreamMeterFuture = new CompletableFuture<>();
         CompletableFuture<Object> downsteamMeterFuture = new CompletableFuture<>();
-        CompletableFuture<ObjectiveError> upFuture = new CompletableFuture();
-        CompletableFuture<ObjectiveError> downFuture = new CompletableFuture();
+        CompletableFuture<ObjectiveError> upFuture = new CompletableFuture<>();
+        CompletableFuture<ObjectiveError> downFuture = new CompletableFuture<>();
 
-        MeterId upstreamMeterId = createMeter(deviceId, upstreamBpInfo, upstreamMeterFuture);
-        MeterId downstreamMeterId = createMeter(deviceId, downstreamBpInfo, downsteamMeterFuture);
+        MeterId upstreamMeterId = oltMeterService.createMeter(deviceId, upstreamBpInfo, upstreamMeterFuture);
+
+        MeterId downstreamMeterId = oltMeterService.createMeter(deviceId, downstreamBpInfo, downsteamMeterFuture);
 
         upstreamMeterFuture.thenAcceptAsync(result -> {
             if (result == null) {
                 log.info("Upstream Meter {} is sent to the device {}. " +
-                        "Sending subscriber flows.", upstreamMeterId, deviceId);
+                                 "Sending subscriber flows.", upstreamMeterId, deviceId);
 
-                ForwardingObjective.Builder upFwd = transparentUpBuilder(uplinkPort, subscriberPort,
-                        innerVlan, outerVlan, upstreamMeterId, subInfo);
+                ForwardingObjective.Builder upFwd =
+                        oltFlowService.createUpBuilder(uplinkPort, subscriberPort, upstreamMeterId, tagInfo);
 
                 flowObjectiveService.forward(deviceId, upFwd.add(new ObjectiveContext() {
                     @Override
                     public void onSuccess(Objective objective) {
+                        log.info("Upstream flow installed successfully");
                         upFuture.complete(null);
                     }
 
@@ -1020,23 +636,30 @@
                     }
                 }));
 
+            } else if (upstreamBpInfo == null) {
+                log.warn("No meter installed since no Upstream BW Profile definition found for " +
+                                 "ctag {} stag {} tpId {} and Device/port: {}:{}",
+                         tagInfo.getPonCTag(), tagInfo.getPonSTag(),
+                         tagInfo.getTechnologyProfileId(),
+                         deviceId, subscriberPort);
             } else {
                 log.warn("Meter installation error while sending upstream flows. " +
-                        "Result {} and MeterId {}", result, upstreamMeterId);
+                                 "Result {} and MeterId {}", result, upstreamMeterId);
             }
         });
 
         downsteamMeterFuture.thenAcceptAsync(result -> {
             if (result == null) {
                 log.info("Downstream Meter {} is sent to the device {}. " +
-                        "Sending subscriber flows.", downstreamMeterId, deviceId);
+                                 "Sending subscriber flows.", downstreamMeterId, deviceId);
 
-                ForwardingObjective.Builder downFwd = transparentDownBuilder(uplinkPort, subscriberPort,
-                        innerVlan, outerVlan, downstreamMeterId, subInfo);
+                ForwardingObjective.Builder downFwd =
+                        oltFlowService.createDownBuilder(uplinkPort, subscriberPort, downstreamMeterId, tagInfo);
 
                 flowObjectiveService.forward(deviceId, downFwd.add(new ObjectiveContext() {
                     @Override
                     public void onSuccess(Objective objective) {
+                        log.info("Downstream flow installed successfully");
                         downFuture.complete(null);
                     }
 
@@ -1045,500 +668,95 @@
                         downFuture.complete(error);
                     }
                 }));
+
+            } else if (downstreamBpInfo == null) {
+                log.warn("No meter installed since no Downstream BW Profile definition found for " +
+                                 "ctag {} stag {} tpId {} and Device/port: {}:{}",
+                         tagInfo.getPonCTag(), tagInfo.getPonSTag(),
+                         tagInfo.getTechnologyProfileId(),
+                         deviceId, subscriberPort);
             } else {
                 log.warn("Meter installation error while sending upstream flows. " +
-                        "Result {} and MeterId {}", result, downstreamMeterId);
+                                 "Result {} and MeterId {}", result, downstreamMeterId);
             }
         });
 
-        additionalVlans.put(cp, new AbstractMap.SimpleEntry(outerVlan, innerVlan));
-
         upFuture.thenAcceptBothAsync(downFuture, (upStatus, downStatus) -> {
+            AccessDeviceEvent.Type type = AccessDeviceEvent.Type.SUBSCRIBER_UNI_TAG_REGISTERED;
             if (downStatus != null) {
                 log.error("Flow with innervlan {} and outerVlan {} on device {} " +
-                                "on port {} failed downstream installation: {}",
-                        innerVlan, outerVlan, deviceId, cp, downStatus);
+                                  "on port {} failed downstream installation: {}",
+                          tagInfo.getPonCTag(), tagInfo.getPonSTag(), deviceId, cp, downStatus);
+                type = AccessDeviceEvent.Type.SUBSCRIBER_UNI_TAG_REGISTRATION_FAILED;
             } else if (upStatus != null) {
                 log.error("Flow with innerVlan {} and outerVlan {} on device {} " +
-                                "on port {} failed upstream installation: {}",
-                        innerVlan, outerVlan, deviceId, cp, upStatus);
+                                  "on port {} failed upstream installation: {}",
+                          tagInfo.getPonCTag(), tagInfo.getPonSTag(), deviceId, cp, upStatus);
+                type = AccessDeviceEvent.Type.SUBSCRIBER_UNI_TAG_REGISTRATION_FAILED;
             } else {
-                processEapolFilteringObjectives(deviceId, subscriberPort, subInfo.upstreamBandwidthProfile(),
-                        null, subInfo.cTag(), true);
+                log.info("Upstream and downstream data plane flows are installed successfully.");
+                oltFlowService.processEapolFilteringObjectives(deviceId, subscriberPort,
+                                                               tagInfo.getUpstreamBandwidthProfile(),
+                                                               null, tagInfo.getPonCTag(), true);
+                if (tagInfo.getIsDhcpRequired()) {
+                    oltFlowService.processDhcpFilteringObjectives(deviceId, subscriberPort,
+                                                                  upstreamMeterId, tagInfo, true, true);
+                }
 
-                // cache subscriber info
-                programmedSubs.put(cp, subInfo);
+                if (tagInfo.getIsIgmpRequired()) {
+                    oltFlowService.processIgmpFilteringObjectives(deviceId, subscriberPort, upstreamMeterId, tagInfo,
+                                                                  true, true);
+                }
+                updateProgrammedSubscriber(cp, tagInfo, true);
+                post(new AccessDeviceEvent(type, deviceId, port, tagInfo.getPonSTag(), tagInfo.getPonCTag(),
+                                           tagInfo.getTechnologyProfileId()));
             }
         }, oltInstallers);
-
     }
 
-    private ForwardingObjective.Builder transparentDownBuilder(PortNumber uplinkPort,
-                                                               PortNumber subscriberPort,
-                                                               VlanId innerVlan,
-                                                               VlanId outerVlan,
-                                                               MeterId downstreamMeterId,
-                                                               SubscriberAndDeviceInformation subInfo) {
-        TrafficSelector downstream = DefaultTrafficSelector.builder()
-                .matchVlanId(outerVlan)
-                .matchInPort(uplinkPort)
-                .matchInnerVlanId(innerVlan)
-                .build();
-
-        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
-        if (downstreamMeterId != null) {
-            tBuilder.meter(downstreamMeterId);
-        }
-
-        TrafficTreatment downstreamTreatment = tBuilder
-                .setOutput(subscriberPort)
-                .writeMetadata(createMetadata(subInfo.cTag(), subInfo.technologyProfileId(), subscriberPort), 0)
-                .build();
-
-        return DefaultForwardingObjective.builder()
-                .withFlag(ForwardingObjective.Flag.VERSATILE)
-                .withPriority(1000)
-                .makePermanent()
-                .withSelector(downstream)
-                .fromApp(appId)
-                .withTreatment(downstreamTreatment);
-    }
-
-    private ForwardingObjective.Builder transparentUpBuilder(PortNumber uplinkPort,
-                                                             PortNumber subscriberPort,
-                                                             VlanId innerVlan,
-                                                             VlanId outerVlan,
-                                                             MeterId upstreamMeterId,
-                                                             SubscriberAndDeviceInformation subInfo) {
-
-        TrafficSelector upstream = DefaultTrafficSelector.builder()
-                .matchVlanId(outerVlan)
-                .matchInPort(subscriberPort)
-                .matchInnerVlanId(innerVlan)
-                .build();
-
-        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
-        if (upstreamMeterId != null) {
-            tBuilder.meter(upstreamMeterId);
-        }
-
-        TrafficTreatment upstreamTreatment = tBuilder
-                .setOutput(uplinkPort)
-                .writeMetadata(createMetadata(subInfo.sTag(), subInfo.technologyProfileId(), uplinkPort), 0)
-                .build();
-
-        return DefaultForwardingObjective.builder()
-                .withFlag(ForwardingObjective.Flag.VERSATILE)
-                .withPriority(1000)
-                .makePermanent()
-                .withSelector(upstream)
-                .fromApp(appId)
-                .withTreatment(upstreamTreatment);
-    }
-
-    private void unprovisionTransparentFlows(DeviceId deviceId, PortNumber uplink,
-                                             PortNumber subscriberPort, VlanId innerVlan,
-                                             VlanId outerVlan) {
-
-        ConnectPoint cp = new ConnectPoint(deviceId, subscriberPort);
-
-        SubscriberAndDeviceInformation subInfo = programmedSubs.get(cp);
+    /**
+     * Checks the subscriber uni tag list and find the uni tag information.
+     * using the pon c tag, pon s tag and the technology profile id
+     * May return Optional<null>
+     *
+     * @param cp        the connection point of the subscriber
+     * @param innerVlan pon c tag
+     * @param outerVlan pon s tag
+     * @param tpId      the technology profile id
+     * @return the found uni tag information
+     */
+    private Optional<UniTagInformation> getUniTagInformation(ConnectPoint cp, VlanId innerVlan, VlanId outerVlan,
+                                                             int tpId) {
+        log.info("Getting uni tag information for cp: {}, innerVlan: {}, outerVlan: {}, tpId: {}", cp, innerVlan,
+                 outerVlan, tpId);
+        SubscriberAndDeviceInformation subInfo = getSubscriber(cp);
         if (subInfo == null) {
-            log.warn("Subscriber is not programmed before for the connectPoint {}", cp);
-            return;
+            log.warn("Subscriber information doesn't exist for the connect point {}", cp);
+            return Optional.empty();
         }
 
-        additionalVlans.remove(cp, new AbstractMap.SimpleEntry(outerVlan, innerVlan));
+        List<UniTagInformation> uniTagList = subInfo.uniTagList();
+        if (uniTagList == null) {
+            log.warn("Uni tag list is not found for the subscriber {}", subInfo.id());
+            return Optional.empty();
+        }
 
-        CompletableFuture<ObjectiveError> downFuture = new CompletableFuture();
-        CompletableFuture<ObjectiveError> upFuture = new CompletableFuture();
-
-        MeterId upstreamMeterId = getMeterIdFromBpMapping(deviceId, subInfo.upstreamBandwidthProfile());
-        MeterId downstreamMeterId = getMeterIdFromBpMapping(deviceId, subInfo.downstreamBandwidthProfile());
-
-        ForwardingObjective.Builder upFwd = transparentUpBuilder(uplink, subscriberPort,
-                innerVlan, outerVlan, upstreamMeterId, subInfo);
-        ForwardingObjective.Builder downFwd = transparentDownBuilder(uplink, subscriberPort,
-                innerVlan, outerVlan, downstreamMeterId, subInfo);
-
-        flowObjectiveService.forward(deviceId, upFwd.remove(new ObjectiveContext() {
-            @Override
-            public void onSuccess(Objective objective) {
-                upFuture.complete(null);
-            }
-
-            @Override
-            public void onError(Objective objective, ObjectiveError error) {
-                upFuture.complete(error);
-            }
-        }));
-
-        flowObjectiveService.forward(deviceId, downFwd.remove(new ObjectiveContext() {
-            @Override
-            public void onSuccess(Objective objective) {
-                downFuture.complete(null);
-            }
-
-            @Override
-            public void onError(Objective objective, ObjectiveError error) {
-                downFuture.complete(error);
-            }
-        }));
-
-        upFuture.thenAcceptBothAsync(downFuture, (upStatus, downStatus) -> {
-            if (downStatus != null) {
-                log.error("Flow with innerVlan {} and outerVlan {} on device {} " +
-                                "on port {} failed downstream uninstallation: {}",
-                        innerVlan, outerVlan, deviceId, subscriberPort, downStatus);
-            } else if (upStatus != null) {
-                log.error("Flow with innerVlan {} and outerVlan {} on device {} " +
-                                "on port {} failed upstream uninstallation: {}",
-                        innerVlan, outerVlan, deviceId, subscriberPort, upStatus);
-            }
-        }, oltInstallers);
-
-        //re-install eapol
-        processEapolFilteringObjectives(deviceId, subscriberPort,
-                subInfo.upstreamBandwidthProfile(), null, subInfo.cTag(), false);
-        processEapolFilteringObjectives(deviceId, subscriberPort, defaultBpId,
-                null, VlanId.vlanId(EAPOL_DEFAULT_VLAN), true);
-
-        programmedMeters.remove(MeterKey.key(deviceId, upstreamMeterId));
-        programmedMeters.remove(MeterKey.key(deviceId, downstreamMeterId));
-    }
-
-    private int getDefaultTechProfileId(DeviceId devId, PortNumber portNumber) {
-        Port port = deviceService.getPort(devId, portNumber);
-        if (port != null) {
-            SubscriberAndDeviceInformation info = subsService.get(port.annotations().value(AnnotationKeys.PORT_NAME));
-            if (info != null && info.technologyProfileId() != -1) {
-                return info.technologyProfileId();
+        UniTagInformation service = null;
+        for (UniTagInformation tagInfo : subInfo.uniTagList()) {
+            if (innerVlan.equals(tagInfo.getPonCTag()) && outerVlan.equals(tagInfo.getPonSTag())
+                    && tpId == tagInfo.getTechnologyProfileId()) {
+                service = tagInfo;
+                break;
             }
         }
-        return defaultTechProfileId;
-    }
 
-    /**
-     * Returns the write metadata value including tech profile reference and innerVlan.
-     * For param cVlan, null can be sent
-     *
-     * @param cVlan         c (customer) tag of one subscriber
-     * @param techProfileId tech profile id of one subscriber
-     * @return the write metadata value including tech profile reference and innerVlan
-     */
-    private Long createTechProfValueForWm(VlanId cVlan, int techProfileId) {
-        if (cVlan == null) {
-            return (long) techProfileId << 32;
-        }
-        return ((long) (cVlan.id()) << 48 | (long) techProfileId << 32);
-    }
-
-    /**
-     * Trap eapol authentication packets to the controller.
-     *
-     * @param devId        the device identifier
-     * @param portNumber   the port for which this trap flow is designated
-     * @param bpId         bandwidth profile id to add the related meter to the flow
-     * @param filterFuture completable future for this filtering objective operation
-     * @param vlanId       the default or customer tag for a subscriber
-     * @param install      true to install the flow, false to remove the flow
-     */
-    private void processEapolFilteringObjectives(DeviceId devId, PortNumber portNumber, String bpId,
-                                                 CompletableFuture<ObjectiveError> filterFuture,
-                                                 VlanId vlanId, boolean install) {
-        if (!enableEapol) {
-            log.debug("Eapol filtering is disabled.");
-            if (filterFuture != null) {
-                filterFuture.complete(null);
-            }
-            return;
+        if (service == null) {
+            log.warn("SADIS doesn't include the service with ponCtag {} ponStag {} and tpId {}",
+                     innerVlan, outerVlan, tpId);
+            return Optional.empty();
         }
 
-        if (!mastershipService.isLocalMaster(devId)) {
-            return;
-        }
-        DefaultFilteringObjective.Builder builder = DefaultFilteringObjective.builder();
-        TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
-        CompletableFuture<Object> meterFuture = new CompletableFuture<>();
-
-        BandwidthProfileInformation bpInfo = getBandwidthProfileInformation(bpId);
-        if (bpInfo == null) {
-            log.warn("Bandwidth profile {} is not found. Authentication flow"
-                    + " will not be installed", bpId);
-            return;
-        }
-
-        // check if meter exists and create it only for an install
-        MeterId meterId = getMeterIdFromBpMapping(devId, bpInfo.id());
-        if (meterId == null) {
-            if (install) {
-                meterId = createMeter(devId, bpInfo, meterFuture);
-                treatmentBuilder.meter(meterId);
-            } else {
-                // this case should not happen as the request to remove an eapol
-                // flow should mean that the flow points to a meter that exists.
-                // Nevertheless we can still delete the flow as we only need the
-                // correct 'match' to do so.
-                log.warn("Unknown meter id for bp {}, still proceeding with "
-                        + "delete of eapol flow for {}/{}", bpInfo.id(), devId,
-                         portNumber);
-                meterFuture.complete(null);
-            }
-        } else {
-            log.debug("Meter {} was previously created for bp {}", meterId,
-                      bpInfo.id());
-            treatmentBuilder.meter(meterId);
-            meterFuture.complete(null);
-        }
-
-        final MeterId mId = meterId;
-        meterFuture.thenAcceptAsync(result -> {
-            if (result == null) {
-                log.info("Meter {} for {} on {}/{} exists. {} EAPOL trap flow",
-                         mId, bpId, devId, portNumber,
-                        (install) ? "Installing " : "Removing ");
-                int techProfileId = getDefaultTechProfileId(devId, portNumber);
-
-                //Authentication trap flow uses only tech profile id as write metadata value
-                FilteringObjective eapol = (install ? builder.permit() : builder.deny())
-                        .withKey(Criteria.matchInPort(portNumber))
-                        .addCondition(Criteria.matchEthType(EthType.EtherType.EAPOL.ethType()))
-                        .addCondition(Criteria.matchVlanId(vlanId))
-                        .withMeta(treatmentBuilder
-                                .writeMetadata(createTechProfValueForWm(vlanId, techProfileId), 0)
-                                .setOutput(PortNumber.CONTROLLER).build())
-                        .fromApp(appId)
-                        .withPriority(10000)
-                        .add(new ObjectiveContext() {
-                            @Override
-                            public void onSuccess(Objective objective) {
-                                log.info("Eapol filter for {} on {} {} with meter {}.",
-                                        devId, portNumber, (install) ? INSTALLED : REMOVED, mId);
-                                if (filterFuture != null) {
-                                    filterFuture.complete(null);
-                                }
-                            }
-
-                            @Override
-                            public void onError(Objective objective, ObjectiveError error) {
-                                log.info("Eapol filter for {} on {} with meter {} failed {} because {}",
-                                        devId, portNumber, mId, (install) ? INSTALLATION : REMOVAL,
-                                        error);
-                                if (filterFuture != null) {
-                                    filterFuture.complete(error);
-                                }
-                            }
-                        });
-
-                flowObjectiveService.filter(devId, eapol);
-            } else {
-                log.warn("Meter installation error while sending eapol trap flow. " +
-                        "Result {} and MeterId {}", result, mId);
-            }
-        });
-    }
-
-    /**
-     * Installs trap filtering objectives for particular traffic types on an
-     * NNI port.
-     *
-     * @param devId   device ID
-     * @param port    port number
-     * @param install true to install, false to remove
-     */
-    private void processNniFilteringObjectives(DeviceId devId, PortNumber port, boolean install) {
-        processLldpFilteringObjective(devId, port, install);
-        processDhcpFilteringObjectives(devId, port, null, -1, install, false);
-    }
-
-    private void processLldpFilteringObjective(DeviceId devId, PortNumber port, boolean install) {
-        if (!mastershipService.isLocalMaster(devId)) {
-            return;
-        }
-        DefaultFilteringObjective.Builder builder = DefaultFilteringObjective.builder();
-
-        FilteringObjective lldp = (install ? builder.permit() : builder.deny())
-                .withKey(Criteria.matchInPort(port))
-                .addCondition(Criteria.matchEthType(EthType.EtherType.LLDP.ethType()))
-                .withMeta(DefaultTrafficTreatment.builder()
-                        .setOutput(PortNumber.CONTROLLER).build())
-                .fromApp(appId)
-                .withPriority(10000)
-                .add(new ObjectiveContext() {
-                    @Override
-                    public void onSuccess(Objective objective) {
-                        log.info("LLDP filter for device {} on port {} {}.",
-                                devId, port, (install) ? INSTALLED : REMOVED);
-                    }
-
-                    @Override
-                    public void onError(Objective objective, ObjectiveError error) {
-                        log.info("LLDP filter for device {} on port {} failed {} because {}",
-                                devId, port, (install) ? INSTALLATION : REMOVAL,
-                                error);
-                    }
-                });
-
-        flowObjectiveService.filter(devId, lldp);
-
-    }
-
-    /**
-     * Trap dhcp packets to the controller.
-     *
-     * @param devId           the device identifier
-     * @param port            the port for which this trap flow is designated
-     * @param upstreamMeterId the upstream meter id that includes the upstream
-     *                        bandwidth profile values such as PIR,CIR. If no meter id needs to be referenced,
-     *                        null can be sent
-     * @param techProfileId   the technology profile id that is used to create write
-     *                        metadata instruction value. If no tech profile id needs to be referenced,
-     *                        -1 can be sent
-     * @param install         true to install the flow, false to remove the flow
-     * @param upstream        true if trapped packets are flowing upstream towards
-     *                        server, false if packets are flowing downstream towards client
-     */
-    private void processDhcpFilteringObjectives(DeviceId devId, PortNumber port,
-                                                MeterId upstreamMeterId,
-                                                int techProfileId,
-                                                boolean install,
-                                                boolean upstream) {
-
-        if (!enableDhcpOnProvisioning) {
-            log.debug("Dhcp provisioning is disabled.");
-            return;
-        }
-
-        if (!mastershipService.isLocalMaster(devId)) {
-            return;
-        }
-
-        if (enableDhcpV4) {
-            int udpSrc = (upstream) ? 68 : 67;
-            int udpDst = (upstream) ? 67 : 68;
-
-            EthType ethType = EthType.EtherType.IPV4.ethType();
-            byte protocol = IPv4.PROTOCOL_UDP;
-
-            this.addDhcpFilteringObjectives(devId, port, udpSrc, udpDst, ethType,
-                    upstreamMeterId, techProfileId, protocol, install);
-        }
-
-        if (enableDhcpV6) {
-            int udpSrc = (upstream) ? 547 : 546;
-            int udpDst = (upstream) ? 546 : 547;
-
-            EthType ethType = EthType.EtherType.IPV6.ethType();
-            byte protocol = IPv6.PROTOCOL_UDP;
-
-            this.addDhcpFilteringObjectives(devId, port, udpSrc, udpDst, ethType,
-                    upstreamMeterId, techProfileId, protocol, install);
-        }
-
-    }
-
-    private void addDhcpFilteringObjectives(DeviceId devId,
-                                            PortNumber port,
-                                            int udpSrc,
-                                            int udpDst,
-                                            EthType ethType,
-                                            MeterId upstreamMeterId,
-                                            int techProfileId,
-                                            byte protocol,
-                                            boolean install) {
-
-        DefaultFilteringObjective.Builder builder = DefaultFilteringObjective.builder();
-        TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
-
-        if (upstreamMeterId != null) {
-            treatmentBuilder.meter(upstreamMeterId);
-        }
-
-        if (techProfileId != -1) {
-            treatmentBuilder.writeMetadata(createTechProfValueForWm(null, techProfileId), 0);
-        }
-
-        FilteringObjective dhcpUpstream = (install ? builder.permit() : builder.deny())
-                .withKey(Criteria.matchInPort(port))
-                .addCondition(Criteria.matchEthType(ethType))
-                .addCondition(Criteria.matchIPProtocol(protocol))
-                .addCondition(Criteria.matchUdpSrc(TpPort.tpPort(udpSrc)))
-                .addCondition(Criteria.matchUdpDst(TpPort.tpPort(udpDst)))
-                .withMeta(treatmentBuilder
-                        .setOutput(PortNumber.CONTROLLER).build())
-                .fromApp(appId)
-                .withPriority(10000)
-                .add(new ObjectiveContext() {
-                    @Override
-                    public void onSuccess(Objective objective) {
-                        log.info("DHCP {} filter for device {} on port {} {}.",
-                                (ethType.equals(EthType.EtherType.IPV4.ethType())) ? "v4" : "v6",
-                                devId, port, (install) ? INSTALLED : REMOVED);
-                    }
-
-                    @Override
-                    public void onError(Objective objective, ObjectiveError error) {
-                        log.info("DHCP {} filter for device {} on port {} failed {} because {}",
-                                (ethType.equals(EthType.EtherType.IPV4.ethType())) ? "v4" : "v6",
-                                devId, port, (install) ? INSTALLATION : REMOVAL,
-                                error);
-                    }
-                });
-
-        flowObjectiveService.filter(devId, dhcpUpstream);
-    }
-
-    private void processIgmpFilteringObjectives(DeviceId devId, PortNumber port,
-                                                MeterId upstreamMeterId,
-                                                int techProfileId,
-                                                boolean install) {
-
-        if (!enableIgmpOnProvisioning) {
-            log.debug("Igmp provisioning is disabled.");
-            return;
-        }
-
-        if (!mastershipService.isLocalMaster(devId)) {
-            return;
-        }
-
-        DefaultFilteringObjective.Builder builder = DefaultFilteringObjective.builder();
-        TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
-
-        if (upstreamMeterId != null) {
-            treatmentBuilder.meter(upstreamMeterId);
-        }
-
-        if (techProfileId != -1) {
-            treatmentBuilder.writeMetadata(createTechProfValueForWm(null, techProfileId), 0);
-        }
-
-        builder = install ? builder.permit() : builder.deny();
-
-        FilteringObjective igmp = builder
-                .withKey(Criteria.matchInPort(port))
-                .addCondition(Criteria.matchEthType(EthType.EtherType.IPV4.ethType()))
-                .addCondition(Criteria.matchIPProtocol(IPv4.PROTOCOL_IGMP))
-                .withMeta(treatmentBuilder
-                        .setOutput(PortNumber.CONTROLLER).build())
-                .fromApp(appId)
-                .withPriority(10000)
-                .add(new ObjectiveContext() {
-                    @Override
-                    public void onSuccess(Objective objective) {
-                        log.info("Igmp filter for {} on {} {}.",
-                                devId, port, (install) ? INSTALLED : REMOVED);
-                    }
-
-                    @Override
-                    public void onError(Objective objective, ObjectiveError error) {
-                        log.info("Igmp filter for {} on {} failed {} because {}.",
-                                devId, port, (install) ? INSTALLATION : REMOVAL,
-                                error);
-                    }
-                });
-
-        flowObjectiveService.filter(devId, igmp);
+        return Optional.of(service);
     }
 
     /**
@@ -1554,16 +772,20 @@
         }
         // check if this device is provisioned in Sadis
         SubscriberAndDeviceInformation deviceInfo = getOltInfo(dev);
-        log.debug("checkAndCreateDeviceFlows: deviceInfo {}", deviceInfo);
+        log.info("checkAndCreateDeviceFlows: deviceInfo {}", deviceInfo);
 
         if (deviceInfo != null) {
             // This is an OLT device as per Sadis, we create flows for UNI and NNI ports
             for (Port p : deviceService.getPorts(dev.id())) {
+                if (PortNumber.LOCAL.equals(p.number())) {
+                    continue;
+                }
                 if (isUniPort(dev, p)) {
-                    processEapolFilteringObjectives(dev.id(), p.number(), defaultBpId, null,
-                            VlanId.vlanId(EAPOL_DEFAULT_VLAN), true);
+                    log.info("Creating Eapol for the uni {}", p);
+                    oltFlowService.processEapolFilteringObjectives(dev.id(), p.number(), defaultBpId, null,
+                                                                   VlanId.vlanId(EAPOL_DEFAULT_VLAN), true);
                 } else {
-                    processNniFilteringObjectives(dev.id(), p.number(), true);
+                    oltFlowService.processNniFilteringObjectives(dev.id(), p.number(), true);
                 }
             }
         }
@@ -1585,7 +807,7 @@
         log.trace("getUplinkPort: deviceInfo {}", deviceInfo);
         if (deviceInfo == null) {
             log.warn("Device {} is not configured in SADIS .. cannot fetch device"
-                    + " info", dev.id());
+                             + " info", dev.id());
             return null;
         }
         // Return the port that has been configured as the uplink port of this OLT in Sadis
@@ -1614,22 +836,12 @@
     }
 
     /**
-     * Write metadata instruction value (metadata) is 8 bytes.
-     * <p>
-     * MS 2 bytes: C Tag
-     * Next 2 bytes: Technology Profile Id
-     * Next 4 bytes: Port number (uni or nni)
+     * Checks whether the given port of the device is a uni port or not.
+     *
+     * @param d the access device
+     * @param p the port of the device
+     * @return true if the given port is a uni port
      */
-
-    private Long createMetadata(VlanId innerVlan, int techProfileId, PortNumber egressPort) {
-
-        if (techProfileId == -1) {
-            techProfileId = defaultTechProfileId;
-        }
-
-        return ((long) (innerVlan.id()) << 48 | (long) techProfileId << 32) | egressPort.toLong();
-    }
-
     private boolean isUniPort(Device d, Port p) {
         Port ulPort = getUplinkPort(d);
         if (ulPort != null) {
@@ -1638,64 +850,18 @@
         return false;
     }
 
+    /**
+     * Gets the given device details from SADIS.
+     * If the device is not found, returns null
+     *
+     * @param dev the access device
+     * @return the olt information
+     */
     private SubscriberAndDeviceInformation getOltInfo(Device dev) {
         String devSerialNo = dev.serialNumber();
         return subsService.get(devSerialNo);
     }
 
-    private MeterId getMeterIdFromBpMapping(DeviceId deviceId, String bandwidthProfile) {
-        if (bpInfoToMeter.get(bandwidthProfile) == null) {
-            log.warn("Bandwidth Profile '{}' is not currently mapped to a meter",
-                      bandwidthProfile);
-            return null;
-        }
-
-        Optional<MeterKey> meterKeyForDevice = bpInfoToMeter.get(bandwidthProfile)
-                .stream()
-                .filter(meterKey -> meterKey.deviceId().equals(deviceId))
-                .findFirst();
-        if (meterKeyForDevice.isPresent()) {
-            log.debug("Found meter {} for bandwidth profile {}",
-                      meterKeyForDevice.get().meterId(), bandwidthProfile);
-            return meterKeyForDevice.get().meterId();
-        } else {
-            log.warn("Bandwidth profile '{}' is not currently mapped to a meter",
-                     bandwidthProfile);
-            return null;
-        }
-    }
-
-    private void addMeterIdToBpMapping(DeviceId deviceId, MeterId meterId, String bandwidthProfile) {
-
-        if (bpInfoToMeter.get(bandwidthProfile) == null) {
-            bpInfoToMeter.put(bandwidthProfile,
-                    new ArrayList<>(Arrays.asList(MeterKey.key(deviceId, meterId))));
-        } else {
-            List<MeterKey> meterKeyListForBp = bpInfoToMeter.get(bandwidthProfile);
-            meterKeyListForBp.add(MeterKey.key(deviceId, meterId));
-        }
-    }
-
-    /**
-     * Removes meter key from programmed meters. If the meter has no reference
-     * count in the data plane and is not present in the programmed-meters store
-     * it will be removed.
-     *
-     * @param deviceId device identifier
-     * @param bandwidthProfileId name of bandwidth profile
-     */
-    private void removeMeterIdFromPrgMeters(DeviceId deviceId,
-                                             String bandwidthProfileId) {
-        List<MeterKey> meterKeysForBp = bpInfoToMeter.get(bandwidthProfileId);
-        if (meterKeysForBp != null) {
-            meterKeysForBp.stream()
-                    .filter(meterKey -> meterKey.deviceId().equals(deviceId))
-                    .findFirst().ifPresent(mk -> {
-                programmedMeters.remove(mk);
-            });
-        }
-    }
-
     private class InternalDeviceListener implements DeviceListener {
         private Set<DeviceId> programmedDevices = Sets.newConcurrentHashSet();
 
@@ -1705,126 +871,131 @@
                 DeviceId devId = event.subject().id();
                 Device dev = event.subject();
                 Port port = event.port();
+                DeviceEvent.Type eventType = event.type();
 
-                if (event.type() == DeviceEvent.Type.PORT_STATS_UPDATED) {
+                if (DeviceEvent.Type.PORT_STATS_UPDATED.equals(eventType) ||
+                        DeviceEvent.Type.DEVICE_SUSPENDED.equals(eventType) ||
+                        DeviceEvent.Type.DEVICE_UPDATED.equals(eventType)) {
                     return;
                 }
 
+                log.debug("OLT got {} event for {} {}", eventType, event.subject(), event.port());
+
                 if (getOltInfo(dev) == null) {
                     // it's possible that we got an event for a previously
                     // programmed OLT that is no longer available in SADIS
                     // we let such events go through
                     if (!programmedDevices.contains(devId)) {
                         log.warn("No device info found for {}, this is either "
-                                + "not an OLT or not known to sadis", dev);
+                                         + "not an OLT or not known to sadis", dev);
                         return;
                     }
                 }
 
-                log.debug("OLT got {} event for {}: {}", event.type(),
-                          event.subject().id(), event);
-
                 switch (event.type()) {
                     //TODO: Port handling and bookkeeping should be improved once
                     // olt firmware handles correct behaviour.
                     case PORT_ADDED:
                         if (isUniPort(dev, port)) {
                             post(new AccessDeviceEvent(AccessDeviceEvent.Type.UNI_ADDED, devId, port));
-                            if (port.isEnabled()) {
-                                processEapolFilteringObjectives(devId, port.number(), defaultBpId,
-                                        null, VlanId.vlanId(EAPOL_DEFAULT_VLAN), true);
+
+                            if (port.isEnabled() && !port.number().equals(PortNumber.LOCAL)) {
+                                log.info("eapol will be sent for port added {}", port);
+                                oltFlowService.processEapolFilteringObjectives(devId, port.number(), defaultBpId,
+                                                                               null,
+                                                                               VlanId.vlanId(EAPOL_DEFAULT_VLAN), true);
                             }
                         } else {
-                            checkAndCreateDeviceFlows(dev);
+                            SubscriberAndDeviceInformation deviceInfo = getOltInfo(dev);
+                            if (deviceInfo != null) {
+                                oltFlowService.processNniFilteringObjectives(dev.id(), port.number(), true);
+                            }
                         }
                         break;
                     case PORT_REMOVED:
                         if (isUniPort(dev, port)) {
                             removeSubscriber(new ConnectPoint(devId, port.number()));
-                            processEapolFilteringObjectives(devId, port.number(), defaultBpId,
-                                    null, VlanId.vlanId(EAPOL_DEFAULT_VLAN), false);
+                            log.info("eapol will be send for port removed", port);
+                            oltFlowService.processEapolFilteringObjectives(devId, port.number(), defaultBpId,
+                                                                           null,
+                                                                           VlanId.vlanId(EAPOL_DEFAULT_VLAN), false);
 
                             post(new AccessDeviceEvent(AccessDeviceEvent.Type.UNI_REMOVED, devId, port));
                         }
-
                         break;
                     case PORT_UPDATED:
                         if (!isUniPort(dev, port)) {
                             break;
                         }
-
-                        SubscriberAndDeviceInformation sub = programmedSubs
+                        Set<UniTagInformation> uniTagInformationSet = programmedSubs
                                 .get(new ConnectPoint(devId, port.number()));
-                        VlanId vlanId = sub == null ? VlanId.vlanId(EAPOL_DEFAULT_VLAN) : sub.cTag();
-
-                        String bpId = getCurrentBandwidthProfile(new ConnectPoint(devId, port.number()));
-
+                        if (uniTagInformationSet == null || uniTagInformationSet.isEmpty()) {
+                            if (port.isEnabled() && !port.number().equals(PortNumber.LOCAL)) {
+                                log.info("eapol will be processed for port updated {}", port);
+                                oltFlowService.processEapolFilteringObjectives(devId, port.number(), DEFAULT_BP_ID,
+                                                                               null,
+                                                                               VlanId.vlanId(EAPOL_DEFAULT_VLAN),
+                                                                               port.isEnabled());
+                            }
+                        } else {
+                            log.info("eapol will be processed for port updated {}", port);
+                            uniTagInformationSet.forEach(uniTag ->
+                                oltFlowService.processEapolFilteringObjectives(devId, port.number(),
+                                    uniTag.getUpstreamBandwidthProfile(), null,
+                                    uniTag.getPonCTag(), port.isEnabled()));
+                        }
                         if (port.isEnabled()) {
-                            processEapolFilteringObjectives(devId, port.number(), bpId,
-                                    null, vlanId, true);
-
                             post(new AccessDeviceEvent(AccessDeviceEvent.Type.UNI_ADDED, devId, port));
                         } else {
-                            processEapolFilteringObjectives(devId, port.number(), bpId,
-                                    null, vlanId, false);
                             post(new AccessDeviceEvent(AccessDeviceEvent.Type.UNI_REMOVED, devId, port));
                         }
                         break;
                     case DEVICE_ADDED:
-                        post(new AccessDeviceEvent(
-                                AccessDeviceEvent.Type.DEVICE_CONNECTED, devId,
-                                null, null));
-                        programmedDevices.add(devId);
-                        // Send UNI_ADDED events for all existing ports
-                        deviceService.getPorts(devId).stream()
-                                .filter(p -> isUniPort(dev, p))
-                                .filter(Port::isEnabled)
-                                .forEach(p -> post(new AccessDeviceEvent(
-                                        AccessDeviceEvent.Type.UNI_ADDED, devId, p)));
-
-                        checkAndCreateDeviceFlows(dev);
+                        handleDeviceConnection(dev, true);
                         break;
                     case DEVICE_REMOVED:
-                        deviceService.getPorts(devId).stream()
-                                .filter(p -> isUniPort(dev, p))
-                                .forEach(p -> post(new AccessDeviceEvent(
-                                        AccessDeviceEvent.Type.UNI_REMOVED, devId, p)));
-                        programmedDevices.remove(devId);
-                        removeAllSubscribers(devId);
-                        post(new AccessDeviceEvent(
-                                AccessDeviceEvent.Type.DEVICE_DISCONNECTED, devId,
-                                null, null));
+                        handleDeviceDisconnection(dev, true);
                         break;
                     case DEVICE_AVAILABILITY_CHANGED:
                         if (deviceService.isAvailable(devId)) {
-                            post(new AccessDeviceEvent(
-                                    AccessDeviceEvent.Type.DEVICE_CONNECTED, devId,
-                                    null, null));
-                            programmedDevices.add(devId);
-                            checkAndCreateDeviceFlows(dev);
+                            handleDeviceConnection(dev, false);
                         } else {
-                            programmedDevices.remove(devId);
-                            removeAllSubscribers(devId);
-                            post(new AccessDeviceEvent(
-                                    AccessDeviceEvent.Type.DEVICE_DISCONNECTED, devId,
-                                    null, null));
+                            handleDeviceDisconnection(dev, false);
                         }
                         break;
-                    case DEVICE_UPDATED:
-                    case DEVICE_SUSPENDED:
-                    case PORT_STATS_UPDATED:
                     default:
                         return;
                 }
             });
         }
 
-        private String getCurrentBandwidthProfile(ConnectPoint connectPoint) {
-            SubscriberAndDeviceInformation sub = programmedSubs.get(connectPoint);
-            if (sub != null) {
-                return sub.upstreamBandwidthProfile();
+        private void sendUniEvent(Device device, AccessDeviceEvent.Type eventType) {
+            deviceService.getPorts(device.id()).stream()
+                    .filter(p -> !PortNumber.LOCAL.equals(p.number()))
+                    .filter(p -> isUniPort(device, p))
+                    .forEach(p -> post(new AccessDeviceEvent(eventType, device.id(), p)));
+        }
+
+        private void handleDeviceDisconnection(Device device, boolean sendUniEvent) {
+            programmedDevices.remove(device.id());
+            removeAllSubscribers(device.id());
+            post(new AccessDeviceEvent(
+                    AccessDeviceEvent.Type.DEVICE_DISCONNECTED, device.id(),
+                    null, null, null));
+            if (sendUniEvent) {
+                sendUniEvent(device, AccessDeviceEvent.Type.UNI_REMOVED);
             }
-            return defaultBpId;
+        }
+
+        private void handleDeviceConnection(Device dev, boolean sendUniEvent) {
+            post(new AccessDeviceEvent(
+                    AccessDeviceEvent.Type.DEVICE_CONNECTED, dev.id(),
+                    null, null, null));
+            programmedDevices.add(dev.id());
+            checkAndCreateDeviceFlows(dev);
+            if (sendUniEvent) {
+                sendUniEvent(dev, AccessDeviceEvent.Type.UNI_ADDED);
+            }
         }
 
         private void removeAllSubscribers(DeviceId deviceId) {
@@ -1834,53 +1005,6 @@
 
             connectPoints.forEach(cp -> programmedSubs.remove(cp));
         }
-    }
 
-    private class InternalMeterListener implements MeterListener {
-
-        @Override
-        public void event(MeterEvent meterEvent) {
-            if (deleteMeters && MeterEvent.Type.METER_REFERENCE_COUNT_ZERO.equals(meterEvent.type())) {
-                log.debug("Zero Count Meter {} received", meterEvent.subject());
-                Meter meter = meterEvent.subject();
-                if (meter != null && appId.equals(meter.appId()) &&
-                        !programmedMeters.contains(MeterKey.key(meter.deviceId(), meter.id()))) {
-                    log.info("Deleting unreferenced, no longer programmed Meter {}",
-                             meter.id());
-                    deleteMeter(meter.deviceId(), meter.id());
-                }
-            } else if (MeterEvent.Type.METER_REMOVED.equals(meterEvent.type())) {
-                log.debug("Meter removed event is received. Meter is {}",
-                          meterEvent.subject());
-                removeMeterFromBpMap(meterEvent.subject());
-            }
-        }
-
-        private void deleteMeter(DeviceId deviceId, MeterId meterId) {
-            Meter meter = meterService.getMeter(deviceId, meterId);
-            if (meter != null) {
-                MeterRequest meterRequest = DefaultMeterRequest.builder()
-                        .withBands(meter.bands())
-                        .withUnit(meter.unit())
-                        .forDevice(deviceId)
-                        .fromApp(appId)
-                        .burst()
-                        .remove();
-
-                meterService.withdraw(meterRequest, meterId);
-            }
-        }
-
-        private void removeMeterFromBpMap(Meter meter) {
-            bpInfoToMeter.values().forEach(meterKeys -> meterKeys.stream()
-                    .filter(meterKey -> (meterKey.deviceId().equals(meter.deviceId()))
-                            && meterKey.meterId().equals(meter.id())).findFirst().
-                            ifPresent(mk -> {
-                                meterKeys.remove(mk);
-                                programmedMeters.remove(mk);
-                                log.info("Deleted from the internal map. MeterKey {}", mk);
-                                log.info("Programmed meters {}", programmedMeters);
-                            }));
-        }
     }
 }
