diff --git a/drivers/src/main/java/org/onosproject/driver/pipeline/OltPipeline.java b/drivers/src/main/java/org/onosproject/driver/pipeline/OltPipeline.java
index 8a7b22b..37980f1 100644
--- a/drivers/src/main/java/org/onosproject/driver/pipeline/OltPipeline.java
+++ b/drivers/src/main/java/org/onosproject/driver/pipeline/OltPipeline.java
@@ -15,8 +15,13 @@
  */
 package org.onosproject.driver.pipeline;
 
+import com.google.common.collect.Lists;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
 import org.onlab.osgi.ServiceDirectory;
 import org.onlab.packet.EthType;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.VlanId;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
 import org.onosproject.net.DefaultAnnotations;
@@ -41,24 +46,38 @@
 import org.onosproject.net.flow.FlowRuleService;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criteria;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.EthTypeCriterion;
+import org.onosproject.net.flow.criteria.IPProtocolCriterion;
+import org.onosproject.net.flow.criteria.PortCriterion;
+import org.onosproject.net.flow.instructions.Instruction;
 import org.onosproject.net.flow.instructions.Instructions;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction;
 import org.onosproject.net.flowobjective.FilteringObjective;
 import org.onosproject.net.flowobjective.ForwardingObjective;
 import org.onosproject.net.flowobjective.NextObjective;
+import org.onosproject.net.flowobjective.Objective;
 import org.onosproject.net.flowobjective.ObjectiveError;
-import org.onosproject.net.packet.PacketPriority;
 import org.onosproject.net.provider.AbstractProvider;
 import org.onosproject.net.provider.ProviderId;
 import org.slf4j.Logger;
 
+import java.util.Collection;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
 import static com.google.common.base.Preconditions.checkNotNull;
 import static org.slf4j.LoggerFactory.getLogger;
 
 /**
  * Pipeliner for OLT device.
  */
+
 public class OltPipeline extends AbstractHandlerBehaviour implements Pipeliner {
 
+    private static final Integer QQ_TABLE = 1;
     private final Logger log = getLogger(getClass());
 
     static final ProviderId PID = new ProviderId("olt", "org.onosproject.olt", true);
@@ -75,110 +94,102 @@
 
     private DeviceProvider provider = new AnnotationProvider();
 
-
     @Override
     public void init(DeviceId deviceId, PipelinerContext context) {
+        log.debug("Initiate OLT pipeline");
         this.serviceDirectory = context.directory();
         this.deviceId = deviceId;
         DeviceProviderRegistry registry =
-               serviceDirectory.get(DeviceProviderRegistry.class);
+                serviceDirectory.get(DeviceProviderRegistry.class);
         flowRuleService = serviceDirectory.get(FlowRuleService.class);
         coreService = serviceDirectory.get(CoreService.class);
 
-        /*try {
-            DeviceProviderService providerService = registry.register(provider);
-            providerService.deviceConnected(deviceId,
-                                            description(deviceId, DEVICE, OLT));
-        } finally {
-            registry.unregister(provider);
-        }*/
-
         appId = coreService.registerApplication(
                 "org.onosproject.driver.OLTPipeline");
 
-        TrafficSelector selector = DefaultTrafficSelector.builder()
-                .matchEthType(EthType.EtherType.EAPOL.ethType().toShort())
-                .build();
-
-        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
-                .punt()
-                .build();
-
-        FlowRule flowRule = new DefaultFlowRule(deviceId, selector, treatment,
-                                                PacketPriority.CONTROL.priorityValue(),
-                                                appId, 0, true, null);
-
-        //flowRuleService.applyFlowRules(flowRule);
     }
 
     @Override
     public void filter(FilteringObjective filter) {
-        throw new UnsupportedOperationException("OLT does not filter.");
-    }
+        Instructions.OutputInstruction output;
 
-    @Override
-    public void forward(ForwardingObjective fwd) {
-        FlowRuleOperations.Builder flowBuilder = FlowRuleOperations.builder();
+        if (filter.meta() != null && !filter.meta().immediate().isEmpty()) {
+            output = (Instructions.OutputInstruction) filter.meta().immediate().stream()
+                    .filter(t -> t.type().equals(Instruction.Type.OUTPUT))
+                    .limit(1)
+                    .findFirst().get();
 
-        if (fwd.flag() != ForwardingObjective.Flag.VERSATILE) {
-            throw new UnsupportedOperationException(
-                    "Only VERSATILE is supported.");
-        }
-
-        boolean isPunt = fwd.treatment().immediate().stream().anyMatch(i -> {
-            if (i instanceof Instructions.OutputInstruction) {
-                Instructions.OutputInstruction out = (Instructions.OutputInstruction) i;
-                return out.port().equals(PortNumber.CONTROLLER);
+            if (output != null && !output.port().equals(PortNumber.CONTROLLER)) {
+                fail(filter, ObjectiveError.UNSUPPORTED);
+                return;
             }
-            return false;
-        });
-
-        if (isPunt) {
+        } else {
+            fail(filter, ObjectiveError.BADPARAMS);
             return;
         }
 
-        TrafficSelector selector = fwd.selector();
+        if (filter.key().type() != Criterion.Type.IN_PORT) {
+            fail(filter, ObjectiveError.BADPARAMS);
+            return;
+        }
+
+        EthTypeCriterion ethType = (EthTypeCriterion)
+                filterForCriterion(filter.conditions(), Criterion.Type.ETH_TYPE);
+
+        if (ethType == null) {
+            fail(filter, ObjectiveError.BADPARAMS);
+            return;
+        }
+
+        if (ethType.ethType().equals(EthType.EtherType.EAPOL)) {
+            provisionEapol(filter, ethType, output);
+        } else if (ethType.ethType().equals(EthType.EtherType.IPV4)) {
+            IPProtocolCriterion ipProto = (IPProtocolCriterion)
+                    filterForCriterion(filter.conditions(), Criterion.Type.IP_PROTO);
+            if (ipProto.protocol() == IPv4.PROTOCOL_IGMP) {
+                provisionIGMP(filter, ethType, ipProto, output);
+            }
+        } else {
+            fail(filter, ObjectiveError.UNSUPPORTED);
+        }
+
+    }
+
+
+    @Override
+    public void forward(ForwardingObjective fwd) {
         TrafficTreatment treatment = fwd.treatment();
 
-        FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
-                .forDevice(deviceId)
-                .withSelector(selector)
-                .withTreatment(treatment)
-                .fromApp(fwd.appId())
-                .withPriority(fwd.priority());
+        List<Instruction> instructions = treatment.allInstructions();
 
-        if (fwd.permanent()) {
-            ruleBuilder.makePermanent();
+        Optional<Instruction> vlanIntruction = instructions.stream()
+                .filter(i -> i.type() == Instruction.Type.L2MODIFICATION)
+                .filter(i -> ((L2ModificationInstruction) i).subtype() ==
+                        L2ModificationInstruction.L2SubType.VLAN_PUSH ||
+                        ((L2ModificationInstruction) i).subtype() ==
+                                L2ModificationInstruction.L2SubType.VLAN_POP)
+                .findAny();
+
+        if (!vlanIntruction.isPresent()) {
+            fail(fwd, ObjectiveError.BADPARAMS);
+            return;
+        }
+
+        L2ModificationInstruction vlanIns =
+                (L2ModificationInstruction) vlanIntruction.get();
+
+        if (vlanIns.subtype() == L2ModificationInstruction.L2SubType.VLAN_PUSH) {
+            installUpstreamRules(fwd);
+        } else if (vlanIns.subtype() == L2ModificationInstruction.L2SubType.VLAN_POP) {
+            installDownstreamRules(fwd);
         } else {
-            ruleBuilder.makeTemporary(fwd.timeout());
+            log.error("Unknown OLT operation: {}", fwd);
+            fail(fwd, ObjectiveError.UNSUPPORTED);
+            return;
         }
 
-        switch (fwd.op()) {
-            case ADD:
-                flowBuilder.add(ruleBuilder.build());
-                break;
-            case REMOVE:
-                flowBuilder.remove(ruleBuilder.build());
-                break;
-            default:
-                log.warn("Unknown operation {}", fwd.op());
-        }
+        pass(fwd);
 
-        flowRuleService.apply(flowBuilder.build(new FlowRuleOperationsContext() {
-            @Override
-            public void onSuccess(FlowRuleOperations ops) {
-                if (fwd.context().isPresent()) {
-                    fwd.context().get().onSuccess(fwd);
-                }
-            }
-
-            @Override
-            public void onError(FlowRuleOperations ops) {
-                if (fwd.context().isPresent()) {
-                    fwd.context().get().onError(fwd, ObjectiveError.FLOWINSTALLATIONFAILED);
-                }
-            }
-        }));
     }
 
     @Override
@@ -186,12 +197,290 @@
         throw new UnsupportedOperationException("OLT does not next hop.");
     }
 
+    private void installDownstreamRules(ForwardingObjective fwd) {
+        List<Pair<Instruction, Instruction>> vlanOps =
+                vlanOps(fwd,
+                        L2ModificationInstruction.L2SubType.VLAN_POP);
+
+        if (vlanOps == null) {
+            return;
+        }
+
+        Instruction output = fetchOutput(fwd, "downstream");
+
+        if (output == null) {
+            return;
+        }
+
+        Pair<Instruction, Instruction> popAndRewrite = vlanOps.remove(0);
+
+        FlowRule.Builder inner = DefaultFlowRule.builder()
+                .forDevice(deviceId)
+                .fromApp(appId)
+                .makePermanent()
+                .withPriority(fwd.priority())
+                .withSelector(fwd.selector())
+                .withTreatment(buildTreatment(popAndRewrite.getLeft(),
+                                              Instructions.transition(QQ_TABLE)));
+        PortCriterion inPort = (PortCriterion)
+                fwd.selector().getCriterion(Criterion.Type.IN_PORT);
+
+        FlowRule.Builder outer = DefaultFlowRule.builder()
+                .forDevice(deviceId)
+                .fromApp(appId)
+                .forTable(QQ_TABLE)
+                .makePermanent()
+                .withPriority(fwd.priority())
+                .withSelector(buildSelector(inPort))
+                .withTreatment(buildTreatment(popAndRewrite.getRight(),
+                                              output));
+
+        applyRules(fwd, inner, outer);
+
+    }
+
+    private void installUpstreamRules(ForwardingObjective fwd) {
+        List<Pair<Instruction, Instruction>> vlanOps =
+                vlanOps(fwd,
+                        L2ModificationInstruction.L2SubType.VLAN_PUSH);
+
+        if (vlanOps == null) {
+            return;
+        }
+
+        Instruction output = fetchOutput(fwd, "upstream");
+
+        if (output == null) {
+            return;
+        }
+
+        Pair<Instruction, Instruction> innerPair = vlanOps.remove(0);
+
+        Pair<Instruction, Instruction> outerPair = vlanOps.remove(0);
+
+        FlowRule.Builder inner = DefaultFlowRule.builder()
+                .forDevice(deviceId)
+                .fromApp(appId)
+                .makePermanent()
+                .withPriority(fwd.priority())
+                .withSelector(fwd.selector())
+                .withTreatment(buildTreatment(innerPair.getRight(),
+                                              Instructions.transition(QQ_TABLE)));
+
+        PortCriterion inPort = (PortCriterion)
+                fwd.selector().getCriterion(Criterion.Type.IN_PORT);
+
+        VlanId cVlanId = ((L2ModificationInstruction.ModVlanIdInstruction)
+                innerPair.getRight()).vlanId();
+
+        FlowRule.Builder outer = DefaultFlowRule.builder()
+                .forDevice(deviceId)
+                .fromApp(appId)
+                .forTable(QQ_TABLE)
+                .makePermanent()
+                .withPriority(fwd.priority())
+                .withSelector(buildSelector(inPort,
+                                            Criteria.matchVlanId(cVlanId)))
+                .withTreatment(buildTreatment(outerPair.getLeft(),
+                                              outerPair.getRight(),
+                                              output));
+
+        applyRules(fwd, inner, outer);
+
+    }
+
+    private Instruction fetchOutput(ForwardingObjective fwd, String direction) {
+        Instruction output = fwd.treatment().allInstructions().stream()
+                .filter(i -> i.type() == Instruction.Type.OUTPUT)
+                .findFirst().orElse(null);
+
+        if (output == null) {
+            log.error("OLT {} rule has no output", direction);
+            fail(fwd, ObjectiveError.BADPARAMS);
+            return null;
+        }
+        return output;
+    }
+
+    private List<Pair<Instruction, Instruction>> vlanOps(ForwardingObjective fwd,
+                                                         L2ModificationInstruction.L2SubType type) {
+
+        List<Pair<Instruction, Instruction>> vlanOps = findVlanOps(
+                fwd.treatment().allInstructions(), type);
+
+        if (vlanOps == null) {
+            String direction = type == L2ModificationInstruction.L2SubType.VLAN_POP
+                    ? "downstream" : "upstream";
+            log.error("Missing vlan operations in {} forwarding: {}", direction, fwd);
+            fail(fwd, ObjectiveError.BADPARAMS);
+            return null;
+        }
+        return vlanOps;
+    }
+
+
+    private List<Pair<Instruction, Instruction>> findVlanOps(List<Instruction> instructions,
+             L2ModificationInstruction.L2SubType type) {
+
+        List<Instruction> vlanPushs = findL2Instructions(
+                type,
+                instructions);
+        List<Instruction> vlanSets = findL2Instructions(
+                L2ModificationInstruction.L2SubType.VLAN_ID,
+                instructions);
+
+        if (vlanPushs.size() != vlanSets.size()) {
+            return null;
+        }
+
+        List<Pair<Instruction, Instruction>> pairs = Lists.newArrayList();
+
+        for (int i = 0; i < vlanPushs.size(); i++) {
+            pairs.add(new ImmutablePair<>(vlanPushs.get(i), vlanSets.get(i)));
+        }
+        return pairs;
+    }
+
+    private List<Instruction> findL2Instructions(L2ModificationInstruction.L2SubType subType,
+                                                 List<Instruction> actions) {
+        return actions.stream()
+                .filter(i -> i.type() == Instruction.Type.L2MODIFICATION)
+                .filter(i -> ((L2ModificationInstruction) i).subtype() == subType)
+                .collect(Collectors.toList());
+    }
+
+    private void provisionEapol(FilteringObjective filter,
+                                EthTypeCriterion ethType,
+                                Instructions.OutputInstruction output) {
+
+        TrafficSelector selector = buildSelector(filter.key(), ethType);
+        TrafficTreatment treatment = buildTreatment(output);
+        buildAndApplyRule(filter, selector, treatment);
+
+    }
+
+    private void provisionIGMP(FilteringObjective filter, EthTypeCriterion ethType,
+                               IPProtocolCriterion ipProto,
+                               Instructions.OutputInstruction output) {
+        TrafficSelector selector = buildSelector(filter.key(), ethType, ipProto);
+        TrafficTreatment treatment = buildTreatment(output);
+        buildAndApplyRule(filter, selector, treatment);
+    }
+
+    private void buildAndApplyRule(FilteringObjective filter, TrafficSelector selector,
+                                   TrafficTreatment treatment) {
+        FlowRule rule = DefaultFlowRule.builder()
+                .forDevice(deviceId)
+                .forTable(0)
+                .fromApp(filter.appId())
+                .makePermanent()
+                .withSelector(selector)
+                .withTreatment(treatment)
+                .build();
+
+        FlowRuleOperations.Builder opsBuilder = FlowRuleOperations.builder();
+
+        switch (filter.type()) {
+            case PERMIT:
+                opsBuilder.add(rule);
+                break;
+            case DENY:
+                opsBuilder.remove(rule);
+                break;
+            default:
+                log.warn("Unknown filter type : {}", filter.type());
+                fail(filter, ObjectiveError.UNSUPPORTED);
+        }
+
+        applyFlowRules(opsBuilder, filter);
+    }
+
+    private void applyRules(ForwardingObjective fwd,
+                            FlowRule.Builder inner, FlowRule.Builder outer) {
+        FlowRuleOperations.Builder builder = FlowRuleOperations.builder();
+        switch (fwd.op()) {
+            case ADD:
+                builder.add(inner.build()).add(outer.build());
+                break;
+            case REMOVE:
+                builder.remove(inner.build()).remove(outer.build());
+                break;
+            case ADD_TO_EXISTING:
+                break;
+            case REMOVE_FROM_EXISTING:
+                break;
+            default:
+                log.warn("Unknown forwarding operation: {}", fwd.op());
+        }
+
+        applyFlowRules(builder, fwd);
+    }
+
+    private void applyFlowRules(FlowRuleOperations.Builder builder,
+                                Objective objective) {
+        flowRuleService.apply(builder.build(new FlowRuleOperationsContext() {
+            @Override
+            public void onSuccess(FlowRuleOperations ops) {
+                pass(objective);
+            }
+
+            @Override
+            public void onError(FlowRuleOperations ops) {
+                fail(objective, ObjectiveError.FLOWINSTALLATIONFAILED);
+            }
+        }));
+    }
+
+    private Criterion filterForCriterion(Collection<Criterion> criteria, Criterion.Type type) {
+        return criteria.stream()
+                .filter(c -> c.type().equals(Criterion.Type.ETH_TYPE))
+                .limit(1)
+                .findFirst().orElse(null);
+    }
+
+    private TrafficSelector buildSelector(Criterion... criteria) {
+
+
+        TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
+
+        for (Criterion c : criteria) {
+            sBuilder.add(c);
+        }
+
+        return sBuilder.build();
+    }
+
+    private TrafficTreatment buildTreatment(Instruction... instructions) {
+
+
+        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+
+        for (Instruction i : instructions) {
+            tBuilder.add(i);
+        }
+
+        return tBuilder.build();
+    }
+
+
+    private void fail(Objective obj, ObjectiveError error) {
+        if (obj.context().isPresent()) {
+            obj.context().get().onError(obj, error);
+        }
+    }
+
+    private void pass(Objective obj) {
+        if (obj.context().isPresent()) {
+            obj.context().get().onSuccess(obj);
+        }
+    }
+
     /**
      * Build a device description.
      *
      * @param deviceId a deviceId
-     * @param key the key of the annotation
-     * @param value the value for the annotation
+     * @param key      the key of the annotation
+     * @param value    the value for the annotation
      * @return a device description
      */
     private DeviceDescription description(DeviceId deviceId, String key, String value) {
