diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/CpqdOfdpa2GroupHandler.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/CpqdOfdpa2GroupHandler.java
index 078e120..9b1d283 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/CpqdOfdpa2GroupHandler.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/CpqdOfdpa2GroupHandler.java
@@ -56,6 +56,9 @@
     protected GroupInfo createL2L3Chain(TrafficTreatment treatment, int nextId,
                                         ApplicationId appId, boolean mpls,
                                         TrafficSelector meta) {
+        if (createUnfiltered(treatment, meta)) {
+            return createUnfilteredL2L3Chain(treatment, nextId, appId);
+        }
         // for the l2interface group, get vlan and port info
         // for the outer group, get the src/dst mac, and vlan info
         TrafficTreatment.Builder outerTtb = DefaultTrafficTreatment.builder();
@@ -281,4 +284,105 @@
         }
         super.processHashedNextObjective(nextObjective);
     }
+
+    /**
+     * Internal implementation of createL2L3Chain to handle double-tagged vlan.
+     * L3UG Group carries dummyVlanId and output port information in its groupId,
+     * and does not set vlan.
+     * L2UG Group only has OUTPUT instruction.
+     *
+     * @param treatment that needs to be broken up to create the group chain
+     * @param nextId of the next objective that needs this group chain
+     * @param appId of the application that sent this next objective
+     * @return GroupInfo containing the GroupDescription of the
+     *         L2 Unfiltered Interface group(inner) and the GroupDescription of the (outer)
+     *         L3Unicast group. May return null if there is an error in processing the chain.
+     */
+    private GroupInfo createUnfilteredL2L3Chain(TrafficTreatment treatment, int nextId,
+                                                ApplicationId appId) {
+        // for the l2 unfiltered interface group, get port info
+        // for the l3 unicast group, get the src/dst mac, and vlan info
+        TrafficTreatment.Builder outerTtb = DefaultTrafficTreatment.builder();
+        TrafficTreatment.Builder innerTtb = DefaultTrafficTreatment.builder();
+        VlanId vlanId = VlanId.NONE;
+        long portNum = 0;
+        MacAddress srcMac;
+        MacAddress dstMac;
+        for (Instruction ins : treatment.allInstructions()) {
+            if (ins.type() == Instruction.Type.L2MODIFICATION) {
+                L2ModificationInstruction l2ins = (L2ModificationInstruction) ins;
+                switch (l2ins.subtype()) {
+                    case ETH_DST:
+                        dstMac = ((L2ModificationInstruction.ModEtherInstruction) l2ins).mac();
+                        outerTtb.setEthDst(dstMac);
+                        break;
+                    case ETH_SRC:
+                        srcMac = ((L2ModificationInstruction.ModEtherInstruction) l2ins).mac();
+                        outerTtb.setEthSrc(srcMac);
+                        break;
+                    case VLAN_ID:
+                        vlanId = ((L2ModificationInstruction.ModVlanIdInstruction) l2ins).vlanId();
+                        break;
+                    default:
+                        break;
+                }
+            } else if (ins.type() == Instruction.Type.OUTPUT) {
+                portNum = ((Instructions.OutputInstruction) ins).port().toLong();
+                innerTtb.add(ins);
+            } else {
+                log.debug("Driver does not handle this type of TrafficTreatment"
+                                  + " instruction in l2l3chain:  {} - {}", ins.type(),
+                          ins);
+            }
+        }
+
+        // assemble information for ofdpa l2 unfiltered interface group
+        int l2groupId = l2UnfilteredGroupId(portNum);
+        // a globally unique groupkey that is different for ports in the same device,
+        // but different for the same portnumber on different devices. Also different
+        // for the various group-types created out of the same next objective.
+        int l2gk = l2UnfilteredGroupKey(deviceId, portNum);
+        final GroupKey l2groupkey = new DefaultGroupKey(Ofdpa2Pipeline.appKryo.serialize(l2gk));
+
+        // assemble information for outer group (L3Unicast)
+        GroupDescription outerGrpDesc;
+        int l3groupId = doubleVlanL3UnicastGroupId(vlanId, portNum);
+        final GroupKey l3groupkey = new DefaultGroupKey(
+                Ofdpa3Pipeline.appKryo.serialize(doubleVlanL3UnicastGroupKey(deviceId, vlanId, portNum)));
+        outerTtb.group(new GroupId(l2groupId));
+        // create the l3unicast group description to wait for the
+        // l2 unfiltered interface group to be processed
+        GroupBucket l3unicastGroupBucket =
+                DefaultGroupBucket.createIndirectGroupBucket(outerTtb.build());
+        outerGrpDesc = new DefaultGroupDescription(
+                deviceId,
+                GroupDescription.Type.INDIRECT,
+                new GroupBuckets(Collections.singletonList(l3unicastGroupBucket)),
+                l3groupkey,
+                l3groupId,
+                appId);
+        log.debug("Trying L3Unicast: device:{} gid:{} gkey:{} nextid:{}",
+                  deviceId, Integer.toHexString(l3groupId),
+                  l3groupkey, nextId);
+
+        // store l2groupkey with the groupChainElem for the outer-group that depends on it
+        OfdpaGroupHandlerUtility.GroupChainElem gce = new OfdpaGroupHandlerUtility.GroupChainElem(
+                outerGrpDesc, 1, false, deviceId);
+        updatePendingGroups(l2groupkey, gce);
+
+        // create group description for the inner l2 unfiltered interface group
+        GroupBucket l2InterfaceGroupBucket =
+                DefaultGroupBucket.createIndirectGroupBucket(innerTtb.build());
+        GroupDescription l2groupDescription =
+                new DefaultGroupDescription(deviceId,
+                                            GroupDescription.Type.INDIRECT,
+                                            new GroupBuckets(Collections.singletonList(l2InterfaceGroupBucket)),
+                                            l2groupkey,
+                                            l2groupId,
+                                            appId);
+        log.debug("Trying L2Unfiltered: device:{} gid:{} gkey:{} nextId:{}",
+                  deviceId, Integer.toHexString(l2groupId), l2groupkey, nextId);
+        return new OfdpaGroupHandlerUtility.GroupInfo(l2groupDescription, outerGrpDesc);
+    }
+
 }
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/CpqdOfdpa2Pipeline.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/CpqdOfdpa2Pipeline.java
index 72b2e8a..898ec44 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/CpqdOfdpa2Pipeline.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/CpqdOfdpa2Pipeline.java
@@ -25,7 +25,10 @@
 import org.onlab.packet.VlanId;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.GroupId;
+import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DeviceId;
+import org.onosproject.driver.extensions.OfdpaMatchActsetOutput;
+import org.onosproject.net.Host;
 import org.onosproject.net.Port;
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.behaviour.NextGroup;
@@ -50,9 +53,12 @@
 import org.onosproject.net.flow.criteria.PortCriterion;
 import org.onosproject.net.flow.criteria.VlanIdCriterion;
 import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flow.instructions.Instructions;
 import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
 import org.onosproject.net.flow.instructions.Instructions.NoActionInstruction;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction;
 import org.onosproject.net.flow.instructions.L3ModificationInstruction;
+import org.onosproject.net.flowobjective.FilteringObjective;
 import org.onosproject.net.flowobjective.ForwardingObjective;
 import org.onosproject.net.flowobjective.ObjectiveError;
 import org.onosproject.net.group.DefaultGroupBucket;
@@ -63,6 +69,7 @@
 import org.onosproject.net.group.GroupBuckets;
 import org.onosproject.net.group.GroupDescription;
 import org.onosproject.net.group.GroupKey;
+import org.onosproject.net.host.HostService;
 import org.onosproject.net.packet.PacketPriority;
 import org.slf4j.Logger;
 
@@ -70,6 +77,7 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Deque;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Objects;
 import java.util.Queue;
@@ -78,12 +86,15 @@
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.locks.ReentrantLock;
+import java.util.Optional;
 
 import static org.onlab.packet.IPv6.PROTOCOL_ICMP6;
 import static org.onlab.packet.MacAddress.BROADCAST;
 import static org.onlab.packet.MacAddress.NONE;
 import static org.onlab.util.Tools.groupedThreads;
 import static org.onosproject.driver.pipeline.ofdpa.OfdpaGroupHandlerUtility.*;
+import static org.onosproject.net.flow.criteria.Criterion.Type.VLAN_VID;
+import static org.onosproject.net.flow.instructions.Instruction.Type.L2MODIFICATION;
 import static org.slf4j.LoggerFactory.getLogger;
 
 
@@ -99,6 +110,8 @@
 
     private final Logger log = getLogger(getClass());
 
+    private static final int EGRESS_VLAN_FLOW_TABLE_IN_INGRESS = 31;
+    private static final int UNICAST_ROUTING_TABLE_1 = 32;
     /**
      * Table that determines whether VLAN is popped before punting to controller.
      * <p>
@@ -193,6 +206,458 @@
             super.init(deviceId, context);
         }
     }
+    protected void processFilter(FilteringObjective filteringObjective,
+                                 boolean install,
+                                 ApplicationId applicationId) {
+        if (isDoubleTagged(filteringObjective)) {
+            processDoubleTaggedFilter(filteringObjective, install, applicationId);
+        } else {
+            // If it is not a double-tagged filter, we fall back
+            // to the OFDPA 2.0 pipeline.
+            super.processFilter(filteringObjective, install, applicationId);
+        }
+    }
+
+    /**
+     * Determines if the filtering objective will be used for double-tagged packets.
+     *
+     * @param fob Filtering objective
+     * @return True if the objective was created for double-tagged packets, false otherwise.
+     */
+    private boolean isDoubleTagged(FilteringObjective fob) {
+        return fob.meta() != null &&
+                fob.meta().allInstructions().stream().anyMatch(inst -> inst.type() == L2MODIFICATION
+                        && ((L2ModificationInstruction) inst).subtype() ==
+                        L2ModificationInstruction.L2SubType.VLAN_POP) &&
+                fob.conditions().stream().filter(criterion -> criterion.type() == VLAN_VID).count() == 2;
+    }
+
+    /**
+     * Determines if the forwarding objective will be used for double-tagged packets.
+     *
+     * @param fwd Forwarding objective
+     * @return True if the objective was created for double-tagged packets, false otherwise.
+     */
+    private boolean isDoubleTagged(ForwardingObjective fwd) {
+        if (fwd.nextId() != null) {
+            NextGroup next = getGroupForNextObjective(fwd.nextId());
+            if (next != null) {
+                List<Deque<GroupKey>> gkeys = appKryo.deserialize(next.data());
+                // we only need the top level group's key
+                Group group = groupService.getGroup(deviceId, gkeys.get(0).peekFirst());
+                if (group != null) {
+                    int groupId = group.id().id();
+                    if (((groupId & ~TYPE_MASK) == L3_UNICAST_TYPE) &&
+                            ((groupId & TYPE_L3UG_DOUBLE_VLAN_MASK) == TYPE_L3UG_DOUBLE_VLAN_MASK)) {
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Configure filtering rules of outer and inner VLAN IDs, and a MAC address.
+     * Filtering happens in three tables (VLAN_TABLE, VLAN_1_TABLE, TMAC_TABLE).
+     *
+     * @param filteringObjective the filtering objective
+     * @param install            true to add, false to remove
+     * @param applicationId      for application programming this filter
+     */
+    private void processDoubleTaggedFilter(FilteringObjective filteringObjective,
+                                           boolean install,
+                                           ApplicationId applicationId) {
+        PortCriterion portCriterion = null;
+        EthCriterion ethCriterion = null;
+        VlanIdCriterion innervidCriterion = null;
+        VlanIdCriterion outerVidCriterion = null;
+        boolean popVlan = false;
+        TrafficTreatment meta = filteringObjective.meta();
+        if (!filteringObjective.key().equals(Criteria.dummy()) &&
+                filteringObjective.key().type() == Criterion.Type.IN_PORT) {
+            portCriterion = (PortCriterion) filteringObjective.key();
+        }
+        if (portCriterion == null) {
+            log.warn("No IN_PORT defined in filtering objective from app: {}" +
+                             "Failed to program VLAN tables.", applicationId);
+            return;
+        } else {
+            log.debug("Received filtering objective for dev/port: {}/{}", deviceId,
+                      portCriterion.port());
+        }
+
+        // meta should have only one instruction, popVlan.
+        if (meta != null && meta.allInstructions().size() == 1) {
+            L2ModificationInstruction l2Inst = (L2ModificationInstruction) meta.allInstructions().get(0);
+            if (l2Inst.subtype().equals(L2ModificationInstruction.L2SubType.VLAN_POP)) {
+                popVlan = true;
+            } else {
+                log.warn("Filtering objective can have only VLAN_POP instruction.");
+                return;
+            }
+        } else {
+            log.warn("Filtering objective should have one instruction.");
+            return;
+        }
+
+        FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
+        for (Criterion criterion : filteringObjective.conditions()) {
+            switch (criterion.type()) {
+                case ETH_DST:
+                case ETH_DST_MASKED:
+                    ethCriterion = (EthCriterion) criterion;
+                    break;
+                case VLAN_VID:
+                    if (innervidCriterion == null) {
+                        innervidCriterion = (VlanIdCriterion) criterion;
+                    } else {
+                        outerVidCriterion = innervidCriterion;
+                        innervidCriterion = (VlanIdCriterion) criterion;
+                    }
+                    break;
+                default:
+                    log.warn("Unsupported filter {}", criterion);
+                    fail(filteringObjective, ObjectiveError.UNSUPPORTED);
+                    return;
+            }
+        }
+
+        if (innervidCriterion == null || outerVidCriterion == null) {
+            log.warn("filtering objective should have two vidCriterion.");
+            return;
+        }
+
+        if (ethCriterion == null || ethCriterion.mac().equals(NONE)) {
+            // NOTE: it is possible that a filtering objective only has vidCriterion
+            log.warn("filtering objective missing dstMac, cannot program TMAC table");
+            return;
+        } else {
+            MacAddress unicastMac = readEthDstFromTreatment(filteringObjective.meta());
+            List<List<FlowRule>> allStages = processEthDstFilter(portCriterion, ethCriterion, innervidCriterion,
+                                                                 innervidCriterion.vlanId(), unicastMac,
+                                                                 applicationId);
+            for (List<FlowRule> flowRules : allStages) {
+                log.trace("Starting a new flow rule stage for TMAC table flow");
+                ops.newStage();
+
+                for (FlowRule flowRule : flowRules) {
+                    log.trace("{} flow rules in TMAC table: {} for dev: {}",
+                              (install) ? "adding" : "removing", flowRules, deviceId);
+                    if (install) {
+                        ops = ops.add(flowRule);
+                    } else {
+                        // NOTE: Only remove TMAC flow when there is no more enabled port within the
+                        // same VLAN on this device if TMAC doesn't support matching on in_port.
+                        if (matchInPortTmacTable()
+                                || (filteringObjective.meta() != null
+                                && filteringObjective.meta().clearedDeferred())) {
+                            ops = ops.remove(flowRule);
+                        } else {
+                            log.debug("Abort TMAC flow removal on {}. Some other ports still share this TMAC flow");
+                        }
+                    }
+                }
+            }
+        }
+
+        List<FlowRule> rules;
+        rules = processDoubleVlanIdFilter(portCriterion, innervidCriterion,
+                                          outerVidCriterion, popVlan, applicationId);
+        for (FlowRule flowRule : rules) {
+            log.trace("{} flow rule in VLAN table: {} for dev: {}",
+                      (install) ? "adding" : "removing", flowRule, deviceId);
+            ops = install ? ops.add(flowRule) : ops.remove(flowRule);
+        }
+
+        // apply filtering flow rules
+        flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
+            @Override
+            public void onSuccess(FlowRuleOperations ops) {
+                log.debug("Applied {} filtering rules in device {}",
+                          ops.stages().get(0).size(), deviceId);
+                pass(filteringObjective);
+            }
+
+            @Override
+            public void onError(FlowRuleOperations ops) {
+                log.info("Failed to apply all filtering rules in dev {}", deviceId);
+                fail(filteringObjective, ObjectiveError.FLOWINSTALLATIONFAILED);
+            }
+        }));
+
+    }
+    /**
+     * Internal implementation of processDoubleVlanIdFilter.
+     *
+     * @param portCriterion       port on device for which this filter is programmed
+     * @param innerVidCriterion   inner vlan
+     * @param outerVidCriterion   outer vlan
+     * @param popVlan             true if outer vlan header needs to be removed
+     * @param applicationId       for application programming this filter
+     * @return flow rules for port-vlan filters
+     */
+    private List<FlowRule> processDoubleVlanIdFilter(PortCriterion portCriterion,
+                                                     VlanIdCriterion innerVidCriterion,
+                                                     VlanIdCriterion outerVidCriterion,
+                                                     boolean popVlan,
+                                                     ApplicationId applicationId) {
+        List<FlowRule> rules = new ArrayList<>();
+        TrafficSelector.Builder outerSelector = DefaultTrafficSelector.builder();
+        TrafficTreatment.Builder outerTreatment = DefaultTrafficTreatment.builder();
+        TrafficSelector.Builder innerSelector = DefaultTrafficSelector.builder();
+        TrafficTreatment.Builder innerTreatment = DefaultTrafficTreatment.builder();
+
+        VlanId outerVlanId = outerVidCriterion.vlanId();
+        VlanId innerVlanId = innerVidCriterion.vlanId();
+        PortNumber portNumber = portCriterion.port();
+        // Check arguments
+        if (PortNumber.ALL.equals(portNumber)
+                || outerVlanId.equals(VlanId.NONE)
+                || innerVlanId.equals(VlanId.NONE)) {
+            log.warn("Incomplete Filtering Objective. " +
+                             "VLAN Table cannot be programmed for {}", deviceId);
+            return ImmutableList.of();
+        } else {
+            outerSelector.matchInPort(portNumber);
+            innerSelector.matchInPort(portNumber);
+            outerTreatment.transition(VLAN_1_TABLE);
+            innerTreatment.transition(TMAC_TABLE);
+            outerTreatment.writeMetadata(outerVlanId.toShort(), 0xFFF);
+
+            outerSelector.matchVlanId(outerVlanId);
+            innerSelector.matchVlanId(innerVlanId);
+            //force recompilation
+            //FIXME might be issue due tu /fff mask
+            innerSelector.matchMetadata(outerVlanId.toShort());
+
+            if (popVlan) {
+                outerTreatment.popVlan();
+            }
+        }
+
+        // NOTE: for double-tagged packets, restore original outer vlan
+        // before sending it to the controller.
+        if (supportPuntGroup()) {
+            GroupKey groupKey = popVlanPuntGroupKey();
+            Group group = groupService.getGroup(deviceId, groupKey);
+            if (group != null) {
+                // push outer vlan and send to controller
+                TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder()
+                        .matchInPort(portNumber)
+                        .matchVlanId(innerVlanId);
+                Host host = handler().get(HostService.class).getConnectedHosts(ConnectPoint.
+                        deviceConnectPoint(deviceId + "/" + portNumber.toLong())).stream().filter(h ->
+                        h.vlan().equals(outerVlanId)).findFirst().orElse(null);
+                EthType vlanType = EthType.EtherType.VLAN.ethType();
+                if (host != null) {
+                    vlanType = host.tpid();
+                }
+                TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder()
+                        .pushVlan(vlanType).setVlanId(outerVlanId).punt();
+
+                rules.add(DefaultFlowRule.builder()
+                        .forDevice(deviceId)
+                        .withSelector(sbuilder.build())
+                        .withTreatment(tbuilder.build())
+                        .withPriority(PacketPriority.CONTROL.priorityValue())
+                        .fromApp(driverId)
+                        .makePermanent()
+                        .forTable(PUNT_TABLE).build());
+            } else {
+                log.info("popVlanPuntGroup not found in dev:{}", deviceId);
+                return Collections.emptyList();
+            }
+        }
+        FlowRule outerRule = DefaultFlowRule.builder()
+                .forDevice(deviceId)
+                .withSelector(outerSelector.build())
+                .withTreatment(outerTreatment.build())
+                .withPriority(DEFAULT_PRIORITY)
+                .fromApp(applicationId)
+                .makePermanent()
+                .forTable(VLAN_TABLE)
+                .build();
+        FlowRule innerRule = DefaultFlowRule.builder()
+                .forDevice(deviceId)
+                .withSelector(innerSelector.build())
+                .withTreatment(innerTreatment.build())
+                .withPriority(DEFAULT_PRIORITY)
+                .fromApp(applicationId)
+                .makePermanent()
+                .forTable(VLAN_1_TABLE)
+                .build();
+        rules.add(outerRule);
+        rules.add(innerRule);
+
+        return rules;
+    }
+
+    /**
+     * In the OF-DPA 2.0 pipeline, egress forwarding objectives go to the
+     * egress tables.
+     * @param fwd  the forwarding objective of type 'egress'
+     * @return     a collection of flow rules to be sent to the switch. An empty
+     *             collection may be returned if there is a problem in processing
+     *             the flow rule
+     */
+    @Override
+    protected Collection<FlowRule> processEgress(ForwardingObjective fwd) {
+        log.debug("Processing egress forwarding objective:{} in dev:{}",
+                  fwd, deviceId);
+
+        List<FlowRule> rules = new ArrayList<>();
+
+        // Build selector
+        TrafficSelector.Builder sb = DefaultTrafficSelector.builder();
+        VlanIdCriterion vlanIdCriterion = (VlanIdCriterion) fwd.selector().getCriterion(Criterion.Type.VLAN_VID);
+        if (vlanIdCriterion == null) {
+            log.error("Egress forwarding objective:{} must include vlanId", fwd.id());
+            fail(fwd, ObjectiveError.BADPARAMS);
+            return rules;
+        }
+
+        Optional<Instruction> outInstr = fwd.treatment().allInstructions().stream()
+                .filter(instruction -> instruction instanceof Instructions.OutputInstruction).findFirst();
+        if (!outInstr.isPresent()) {
+            log.error("Egress forwarding objective:{} must include output port", fwd.id());
+            fail(fwd, ObjectiveError.BADPARAMS);
+            return rules;
+        }
+
+        PortNumber portNumber = ((Instructions.OutputInstruction) outInstr.get()).port();
+
+        sb.matchVlanId(vlanIdCriterion.vlanId());
+        OfdpaMatchActsetOutput actsetOutput = new OfdpaMatchActsetOutput(portNumber);
+        sb.extension(actsetOutput, deviceId);
+
+        // Build a flow rule for Egress VLAN Flow table
+        TrafficTreatment.Builder tb = DefaultTrafficTreatment.builder();
+        tb.transition(UNICAST_ROUTING_TABLE_1);
+        if (fwd.treatment() != null) {
+            for (Instruction instr : fwd.treatment().allInstructions()) {
+                if (instr instanceof L2ModificationInstruction &&
+                        ((L2ModificationInstruction) instr).subtype() ==
+                                L2ModificationInstruction.L2SubType.VLAN_ID) {
+                    tb.immediate().add(instr);
+                }
+                if (instr instanceof L2ModificationInstruction &&
+                        ((L2ModificationInstruction) instr).subtype() ==
+                                L2ModificationInstruction.L2SubType.VLAN_PUSH) {
+                    EthType ethType = ((L2ModificationInstruction.ModVlanHeaderInstruction) instr).ethernetType();
+                    tb.immediate().pushVlan(ethType);
+                }
+            }
+        }
+
+        FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
+                .fromApp(fwd.appId())
+                .withPriority(fwd.priority())
+                .forDevice(deviceId)
+                .withSelector(sb.build())
+                .withTreatment(tb.build())
+                .makePermanent()
+                .forTable(EGRESS_VLAN_FLOW_TABLE_IN_INGRESS);
+        rules.add(ruleBuilder.build());
+        return rules;
+    }
+
+    /**
+     * Handles forwarding rules to the IP Unicast Routing.
+     *
+     * @param fwd the forwarding objective
+     * @return A collection of flow rules, or an empty set
+     */
+    protected Collection<FlowRule> processDoubleTaggedFwd(ForwardingObjective fwd) {
+        // inner for UNICAST_ROUTING_TABLE_1, outer for UNICAST_ROUTING_TABLE
+        TrafficSelector selector = fwd.selector();
+        TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
+        TrafficTreatment.Builder innerTtb = DefaultTrafficTreatment.builder();
+        TrafficTreatment.Builder outerTtb = DefaultTrafficTreatment.builder();
+
+        EthTypeCriterion ethType =
+                (EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE);
+
+        if (ethType.ethType().toShort() == Ethernet.TYPE_IPV4) {
+            sBuilder.matchEthType(Ethernet.TYPE_IPV4);
+            sBuilder.matchVlanId(VlanId.ANY);
+            IpPrefix ipv4Dst = ((IPCriterion) selector.getCriterion(Criterion.Type.IPV4_DST)).ip();
+            if (!ipv4Dst.isMulticast() && ipv4Dst.prefixLength() == 32) {
+                sBuilder.matchIPDst(ipv4Dst);
+                if (fwd.nextId() != null) {
+                    NextGroup next = getGroupForNextObjective(fwd.nextId());
+                    if (next != null) {
+                        List<Deque<GroupKey>> gkeys = appKryo.deserialize(next.data());
+                        // we only need the top level group's key to point the flow to it
+                        Group group = groupService.getGroup(deviceId, gkeys.get(0).peekFirst());
+                        if (group == null) {
+                            log.warn("Group with key:{} for next-id:{} not found in dev:{}",
+                                     gkeys.get(0).peekFirst(), fwd.nextId(), deviceId);
+                            fail(fwd, ObjectiveError.GROUPMISSING);
+                            return Collections.emptySet();
+                        }
+                        outerTtb.immediate().setVlanId(extractDummyVlanIdFromGroupId(group.id().id()));
+                        //ACTSET_OUTPUT in OVS will match output action in write_action() set.
+                        outerTtb.deferred().setOutput(extractOutputPortFromGroupId(group.id().id()));
+                        outerTtb.transition(EGRESS_VLAN_FLOW_TABLE_IN_INGRESS);
+                        innerTtb.deferred().group(group.id());
+                        innerTtb.transition(ACL_TABLE);
+
+                        FlowRule.Builder innerRuleBuilder = DefaultFlowRule.builder()
+                                .fromApp(fwd.appId())
+                                .withPriority(fwd.priority())
+                                .forDevice(deviceId)
+                                .withSelector(sBuilder.build())
+                                .withTreatment(innerTtb.build())
+                                .forTable(UNICAST_ROUTING_TABLE_1);
+                        if (fwd.permanent()) {
+                            innerRuleBuilder.makePermanent();
+                        } else {
+                            innerRuleBuilder.makeTemporary(fwd.timeout());
+                        }
+                        Collection<FlowRule> flowRuleCollection = new HashSet<>();
+                        flowRuleCollection.add(innerRuleBuilder.build());
+
+                        FlowRule.Builder outerRuleBuilder = DefaultFlowRule.builder()
+                                .fromApp(fwd.appId())
+                                .withPriority(fwd.priority())
+                                .forDevice(deviceId)
+                                .withSelector(sBuilder.build())
+                                .withTreatment(outerTtb.build())
+                                .forTable(UNICAST_ROUTING_TABLE);
+                        if (fwd.permanent()) {
+                            outerRuleBuilder.makePermanent();
+                        } else {
+                            outerRuleBuilder.makeTemporary(fwd.timeout());
+                        }
+                        flowRuleCollection.add(innerRuleBuilder.build());
+                        flowRuleCollection.add(outerRuleBuilder.build());
+                        return flowRuleCollection;
+                    } else {
+                        log.warn("Cannot find group for nextId:{} in dev:{}. Aborting fwd:{}",
+                                 fwd.nextId(), deviceId, fwd.id());
+                        fail(fwd, ObjectiveError.FLOWINSTALLATIONFAILED);
+                        return Collections.emptySet();
+                    }
+                } else {
+                    log.warn("NextId is not specified in fwd:{}", fwd.id());
+                    fail(fwd, ObjectiveError.FLOWINSTALLATIONFAILED);
+                    return Collections.emptySet();
+                }
+            }
+        }
+        return Collections.emptySet();
+    }
+
+    private static VlanId extractDummyVlanIdFromGroupId(int groupId) {
+        short vlanId = (short) ((groupId & 0x7FF8000) >> 15);
+        return VlanId.vlanId(vlanId);
+    }
+
+    private static PortNumber extractOutputPortFromGroupId(int groupId) {
+        return PortNumber.portNumber(groupId & 0x7FFF);
+    }
+
     /*
      * Cpqd emulation does not require the non OF-standard rules for
      * matching untagged packets that ofdpa uses.
@@ -528,6 +993,9 @@
      */
     @Override
     protected Collection<FlowRule> processEthTypeSpecific(ForwardingObjective fwd) {
+        if (isDoubleTagged(fwd)) {
+            return processDoubleTaggedFwd(fwd);
+        }
         TrafficSelector selector = fwd.selector();
         EthTypeCriterion ethType =
                 (EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE);
@@ -682,7 +1150,7 @@
         EthCriterion ethCriterion = (EthCriterion) selector
                 .getCriterion(Criterion.Type.ETH_DST);
         VlanIdCriterion vlanIdCriterion = (VlanIdCriterion) selector
-                .getCriterion(Criterion.Type.VLAN_VID);
+                .getCriterion(VLAN_VID);
 
         if (vlanIdCriterion == null) {
             log.warn("Forwarding objective for bridging requires vlan. Not "
@@ -841,9 +1309,12 @@
     protected void initializePipeline() {
         initTableMiss(PORT_TABLE, VLAN_TABLE, null);
         initTableMiss(VLAN_TABLE, ACL_TABLE, null);
+        initTableMiss(VLAN_1_TABLE, ACL_TABLE, null);
         initTableMiss(TMAC_TABLE, BRIDGING_TABLE, null);
         initTableMiss(UNICAST_ROUTING_TABLE, ACL_TABLE, null);
         initTableMiss(MULTICAST_ROUTING_TABLE, ACL_TABLE, null);
+        initTableMiss(EGRESS_VLAN_FLOW_TABLE_IN_INGRESS, ACL_TABLE, null);
+        initTableMiss(UNICAST_ROUTING_TABLE_1, ACL_TABLE, null);
         initTableMiss(MPLS_TABLE_0, MPLS_TABLE_1, null);
         initTableMiss(MPLS_TABLE_1, ACL_TABLE, null);
         initTableMiss(BRIDGING_TABLE, ACL_TABLE, null);
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/OfdpaGroupHandlerUtility.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/OfdpaGroupHandlerUtility.java
index 002df22..31b92a8 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/OfdpaGroupHandlerUtility.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/OfdpaGroupHandlerUtility.java
@@ -27,6 +27,8 @@
 import org.onosproject.net.flow.DefaultTrafficTreatment;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.VlanIdCriterion;
 import org.onosproject.net.flow.instructions.Instruction;
 import org.onosproject.net.flow.instructions.Instructions;
 import org.onosproject.net.flow.instructions.L2ModificationInstruction;
@@ -60,6 +62,7 @@
      * OFDPA requires group-id's to have a certain form.
      * L2 Interface Groups have <4bits-0><12bits-vlanId><16bits-portId>
      * L3 Unicast Groups have <4bits-2><28bits-index>
+     * L3 Unicast Groups for double-vlan have <4bits-2><1bit-1><12bits-vlanId><15bits-portId>
      * MPLS Interface Groups have <4bits-9><4bits:0><24bits-index>
      * L3 ECMP Groups have <4bits-7><28bits-index>
      * L2 Flood Groups have <4bits-4><12bits-vlanId><16bits-index>
@@ -78,6 +81,7 @@
     static final int TYPE_MASK = 0x0fffffff;
     static final int SUBTYPE_MASK = 0x00ffffff;
     static final int TYPE_VLAN_MASK = 0x0000ffff;
+    static final int TYPE_L3UG_DOUBLE_VLAN_MASK = 0x08000000;
 
     static final int THREE_BIT_MASK = 0x0fff;
     static final int FOUR_BIT_MASK = 0xffff;
@@ -710,4 +714,52 @@
             }
         }
     }
+
+    /**
+     * Helper method to decide whether L2 Interface group or L2 Unfiltered group needs to be created.
+     * L2 Unfiltered group will be created if meta has VlanIdCriterion with VlanId.ANY, and
+     * treatment has set Vlan ID action.
+     *
+     * @param treatment  treatment passed in by the application as part of the nextObjective
+     * @param meta       metadata passed in by the application as part of the nextObjective
+     * @return true if L2 Unfiltered group needs to be created, false otherwise.
+     */
+    public static boolean createUnfiltered(TrafficTreatment treatment, TrafficSelector meta) {
+        if (meta == null || treatment == null) {
+            return false;
+        }
+        VlanIdCriterion vlanIdCriterion = (VlanIdCriterion) meta.getCriterion(Criterion.Type.VLAN_VID);
+        if (vlanIdCriterion == null || !vlanIdCriterion.vlanId().equals(VlanId.ANY)) {
+            return false;
+        }
+
+        return treatment.allInstructions().stream()
+                .filter(i -> (i.type() == Instruction.Type.L2MODIFICATION
+                        && ((L2ModificationInstruction) i).subtype() == L2ModificationInstruction.L2SubType.VLAN_ID))
+                .count() == 1;
+    }
+
+    /**
+     * Returns a hash as the L3 Unicast Group Key.
+     *
+     * Keep the lower 6-bit for port since port number usually smaller than 64.
+     * Hash other information into remaining 28 bits.
+     *
+     * @param deviceId Device ID
+     * @param vlanId vlan ID
+     * @param portNumber Port number
+     * @return L3 unicast group key
+     */
+    public static int doubleVlanL3UnicastGroupKey(DeviceId deviceId, VlanId vlanId, long portNumber) {
+        int portLowerBits = (int) portNumber & PORT_LOWER_BITS_MASK;
+        long portHigherBits = portNumber & PORT_HIGHER_BITS_MASK;
+        int hash = Objects.hash(deviceId, portHigherBits, vlanId);
+        return  L3_UNICAST_TYPE | (TYPE_MASK & hash << 6) | portLowerBits;
+    }
+
+    public static int doubleVlanL3UnicastGroupId(VlanId vlanId, long portNum) {
+        // <4bits-2><1bit-1><12bits-vlanId><15bits-portId>
+        return L3_UNICAST_TYPE | 1 << 27 | (vlanId.toShort() << 15) | (int) (portNum & 0x7FFF);
+    }
+
 }
