diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
index 2d4cc45..1423e06 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
@@ -74,6 +74,7 @@
 import org.onosproject.net.packet.PacketContext;
 import org.onosproject.net.packet.PacketProcessor;
 import org.onosproject.net.packet.PacketService;
+import org.onosproject.net.topology.PathService;
 import org.onosproject.net.topology.TopologyService;
 import org.onosproject.routing.config.RouterConfig;
 import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
@@ -134,6 +135,9 @@
     private NeighbourResolutionService neighbourResolutionService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    public PathService pathService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     CoreService coreService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
@@ -146,16 +150,16 @@
     DeviceService deviceService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    FlowObjectiveService flowObjectiveService;
+    public FlowObjectiveService flowObjectiveService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     LinkService linkService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    MastershipService mastershipService;
+    public MastershipService mastershipService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    StorageService storageService;
+    public StorageService storageService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     MulticastRouteService multicastRouteService;
@@ -180,7 +184,7 @@
     IpHandler ipHandler = null;
     RoutingRulePopulator routingRulePopulator = null;
     public ApplicationId appId;
-    protected DeviceConfiguration deviceConfiguration = null;
+    public DeviceConfiguration deviceConfiguration = null;
 
     DefaultRoutingHandler defaultRoutingHandler = null;
     private TunnelHandler tunnelHandler = null;
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/pwaas/L2TunnelHandler.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/pwaas/L2TunnelHandler.java
index 96fe6c9..5f0ed35 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/pwaas/L2TunnelHandler.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/pwaas/L2TunnelHandler.java
@@ -16,36 +16,166 @@
 
 package org.onosproject.segmentrouting.pwaas;
 
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import org.apache.commons.lang3.RandomUtils;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.MplsLabel;
+import org.onlab.packet.VlanId;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.DisjointPath;
+import org.onosproject.net.Link;
+import org.onosproject.net.PortNumber;
 import org.onosproject.net.config.NetworkConfigEvent;
+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.DefaultNextObjective;
+import org.onosproject.net.flowobjective.DefaultObjectiveContext;
+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.ObjectiveContext;
+import org.onosproject.net.flowobjective.ObjectiveError;
 import org.onosproject.segmentrouting.SegmentRoutingManager;
+import org.onosproject.segmentrouting.SegmentRoutingService;
+import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
 import org.onosproject.segmentrouting.config.PwaasConfig;
+import org.onosproject.store.serializers.KryoNamespaces;
+import org.onosproject.store.service.ConsistentMap;
+import org.onosproject.store.service.Serializer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkState;
+import static org.onosproject.net.flowobjective.ForwardingObjective.Flag.VERSATILE;
+import static org.onosproject.segmentrouting.pwaas.L2Mode.TAGGED;
+import static org.onosproject.segmentrouting.pwaas.L2TunnelHandler.Pipeline.INITIATION;
+import static org.onosproject.segmentrouting.pwaas.L2TunnelHandler.Result.*;
+
 /**
  * Handles pwaas related events.
  */
 public class L2TunnelHandler {
+
     private static final Logger log = LoggerFactory.getLogger(L2TunnelHandler.class);
-    private static final String CONFIG_NOT_FOUND = "Pwaas config not found";
+
+    private static final String FWD = "f";
+    private static final String REV = "r";
+
     private static final String NOT_MASTER = "Not master controller";
+    private static final String WRONG_TOPOLOGY = "Path in leaf-spine topology" +
+            " should always be two hops: ";
+
     private final SegmentRoutingManager srManager;
 
-    public L2TunnelHandler(SegmentRoutingManager srManager) {
-        this.srManager = srManager;
+    private final ConsistentMap<String, NextObjective> l2InitiationNextObjStore;
+
+    /**
+     * TODO a proper store is necessary to handle the policies and collisions.
+     */
+    private final KryoNamespace.Builder l2TunnelKryo;
+
+    /**
+     * Create a l2 tunnel handler for the deploy and
+     * for the tear down of pseudo wires.
+     *
+     * @param segmentRoutingManager the segment routing manager
+     */
+    public L2TunnelHandler(SegmentRoutingManager segmentRoutingManager) {
+        srManager = segmentRoutingManager;
+        l2TunnelKryo = new KryoNamespace.Builder()
+                .register(KryoNamespaces.API);
+
+        l2InitiationNextObjStore = srManager.storageService
+                .<String, NextObjective>consistentMapBuilder()
+                .withName("onos-l2initiation-nextobj-store")
+                .withSerializer(Serializer.using(l2TunnelKryo.build()))
+                .build();
     }
 
     /**
      * Processes Pwaas Config added event.
      *
-     * @param event network config added event
+     * @param event network config add event
      */
     public void processPwaasConfigAdded(NetworkConfigEvent event) {
         log.info("Processing Pwaas CONFIG_ADDED");
         PwaasConfig config = (PwaasConfig) event.config().get();
-        config.getPwIds().forEach(pwId -> {
-            log.info("{}", config.getPwDescription(pwId));
-        });
+        Set<DefaultL2TunnelDescription> pwToAdd = config.getPwIds()
+                .stream()
+                .map(config::getPwDescription)
+                .collect(Collectors.toSet());
+        // We deploy all the pseudo wire deployed
+        deploy(pwToAdd);
+    }
+
+    private void deploy(Set<DefaultL2TunnelDescription> pwToAdd) {
+        Result result;
+        long l2TunnelId;
+        for (DefaultL2TunnelDescription currentL2Tunnel : pwToAdd) {
+            l2TunnelId = currentL2Tunnel.l2Tunnel().tunnelId();
+            // The tunnel id cannot be 0.
+            if (l2TunnelId == 0) {
+                log.warn("Tunnel id cannot be 0");
+                continue;
+            }
+            // We do a sanity check of the pseudo wire.
+            result = verifyPseudoWire(currentL2Tunnel);
+            if (result != SUCCESS) {
+                continue;
+            }
+            // We establish the tunnel.
+            result = deployPseudoWire(
+                    currentL2Tunnel.l2Tunnel(),
+                    currentL2Tunnel.l2TunnelPolicy().cP1(),
+                    currentL2Tunnel.l2TunnelPolicy().cP2(),
+                    FWD
+            );
+            if (result != SUCCESS) {
+                continue;
+            }
+            // We create the policy.
+            result = deployPolicy(
+                    l2TunnelId,
+                    currentL2Tunnel.l2TunnelPolicy().cP1(),
+                    currentL2Tunnel.l2TunnelPolicy().cP1InnerTag(),
+                    currentL2Tunnel.l2TunnelPolicy().cP1OuterTag(),
+                    result.nextId
+            );
+            if (result != SUCCESS) {
+                continue;
+            }
+            // We establish the reverse tunnel.
+            result = deployPseudoWire(
+                    currentL2Tunnel.l2Tunnel(),
+                    currentL2Tunnel.l2TunnelPolicy().cP2(),
+                    currentL2Tunnel.l2TunnelPolicy().cP1(),
+                    REV
+            );
+            if (result != SUCCESS) {
+                continue;
+            }
+            deployPolicy(
+                    l2TunnelId,
+                    currentL2Tunnel.l2TunnelPolicy().cP2(),
+                    currentL2Tunnel.l2TunnelPolicy().cP2InnerTag(),
+                    currentL2Tunnel.l2TunnelPolicy().cP2OuterTag(),
+                    result.nextId
+            );
+        }
     }
 
     /**
@@ -55,9 +185,161 @@
      */
     public void processPwaasConfigUpdated(NetworkConfigEvent event) {
         log.info("Processing Pwaas CONFIG_UPDATED");
+        // We retrieve the old pseudo wires.
+        PwaasConfig prevConfig = (PwaasConfig) event.prevConfig().get();
+        Set<Long> prevPws = prevConfig.getPwIds();
+        // We retrieve the new pseudo wires.
         PwaasConfig config = (PwaasConfig) event.config().get();
-        config.getPwIds().forEach(pwId -> {
-            log.info("{}", config.getPwDescription(pwId));
+        Set<Long> newPws = config.getPwIds();
+        // We compute the pseudo wires to update.
+        Set<Long> updPws = newPws.stream()
+                .filter(tunnelId -> prevPws.contains(tunnelId) &&
+                !config.getPwDescription(tunnelId).equals(prevConfig.getPwDescription(tunnelId)))
+                .collect(Collectors.toSet());
+        // The pseudo wires to remove.
+        Set<DefaultL2TunnelDescription> pwToRemove = prevPws.stream()
+                .filter(tunnelId -> !newPws.contains(tunnelId))
+                .map(prevConfig::getPwDescription)
+                .collect(Collectors.toSet());
+        tearDown(pwToRemove);
+        // The pseudo wires to add.
+        Set<DefaultL2TunnelDescription> pwToAdd = newPws.stream()
+                .filter(tunnelId -> !prevPws.contains(tunnelId))
+                .map(config::getPwDescription)
+                .collect(Collectors.toSet());
+        deploy(pwToAdd);
+        // The pseudo wires to update.
+        updPws.forEach(tunnelId -> {
+            updatePw(
+                    prevConfig.getPwDescription(tunnelId),
+                    config.getPwDescription(tunnelId)
+            );
+        });
+    }
+
+    /**
+     * Helper function to update a pw.
+     *
+     * @param oldPw the pseudo wire to remove
+     * @param newPw the pseudo wirte to add
+     */
+    private void updatePw(DefaultL2TunnelDescription oldPw,
+                          DefaultL2TunnelDescription newPw) {
+
+        long tunnelId = oldPw.l2Tunnel().tunnelId();
+        String fwdKey = generateKey(tunnelId, FWD);
+        String revKey = generateKey(tunnelId, REV);
+        Result result;
+        NextObjective fwdNextObjective;
+        NextObjective revNextObjective;
+        // The async tasks to orchestrate the next and
+        // forwarding update.
+        CompletableFuture<ObjectiveError> revPolicyFuture = new CompletableFuture<>();
+        CompletableFuture<ObjectiveError> fwdInitNextFuture = new CompletableFuture<>();
+        CompletableFuture<ObjectiveError> revInitNextFuture = new CompletableFuture<>();
+        CompletableFuture<ObjectiveError> newPwFuture = new CompletableFuture<>();
+
+        result = verifyPseudoWire(newPw);
+        if (result != SUCCESS) {
+            return;
+        }
+        if (!l2InitiationNextObjStore.containsKey(fwdKey)) {
+            log.warn("NextObj for {} does not exist in the store.", fwdKey);
+            return;
+        }
+        fwdNextObjective = l2InitiationNextObjStore.get(fwdKey).value();
+        if (!l2InitiationNextObjStore.containsKey(revKey)) {
+            log.warn("NextObj for {} does not exist in the store.", revKey);
+            return;
+        }
+        // First we remove both policy.
+        revNextObjective = l2InitiationNextObjStore.get(revKey).value();
+        log.debug("Start deleting fwd policy for {}", tunnelId);
+        deletePolicy(
+                tunnelId,
+                oldPw.l2TunnelPolicy().cP1(),
+                oldPw.l2TunnelPolicy().cP1InnerTag(),
+                oldPw.l2TunnelPolicy().cP1OuterTag(),
+                fwdNextObjective.id(),
+                revPolicyFuture
+        );
+        revPolicyFuture.thenAcceptAsync(status -> {
+            if (status == null) {
+                log.debug("Fwd policy removed. Now remove rev policy for {}", tunnelId);
+                deletePolicy(
+                        tunnelId,
+                        oldPw.l2TunnelPolicy().cP2(),
+                        oldPw.l2TunnelPolicy().cP2InnerTag(),
+                        oldPw.l2TunnelPolicy().cP2OuterTag(),
+                        revNextObjective.id(),
+                        fwdInitNextFuture
+                );
+            }
+        });
+        // Finally we remove both the tunnels.
+        fwdInitNextFuture.thenAcceptAsync(status -> {
+            if (status == null) {
+                log.debug("Rev policy removed. Now remove fwd pw for {}", tunnelId);
+                tearDownPseudoWire(
+                        fwdKey,
+                        fwdNextObjective,
+                        oldPw.l2TunnelPolicy().cP1(),
+                        oldPw.l2TunnelPolicy().cP2(),
+                        revInitNextFuture
+                );
+            }
+        });
+        revInitNextFuture.thenAcceptAsync(status -> {
+           if (status == null) {
+               log.debug("Fwd tunnel removed. Now remove rev pw for {}", tunnelId);
+               tearDownPseudoWire(
+                       revKey,
+                       revNextObjective,
+                       oldPw.l2TunnelPolicy().cP2(),
+                       oldPw.l2TunnelPolicy().cP1(),
+                       newPwFuture
+               );
+
+           }
+        });
+        // At the end we install the new pw.
+        newPwFuture.thenAcceptAsync(status -> {
+            if (status == null) {
+                log.debug("Deploying new fwd pw for {}", tunnelId);
+                Result lamdaResult = deployPseudoWire(
+                        newPw.l2Tunnel(),
+                        newPw.l2TunnelPolicy().cP1(),
+                        newPw.l2TunnelPolicy().cP2(),
+                        FWD
+                );
+                if (lamdaResult != SUCCESS) {
+                    return;
+                }
+                lamdaResult = deployPolicy(
+                        tunnelId,
+                        newPw.l2TunnelPolicy().cP1(),
+                        newPw.l2TunnelPolicy().cP1InnerTag(),
+                        newPw.l2TunnelPolicy().cP1OuterTag(),
+                        lamdaResult.nextId
+                );
+                log.debug("Deploying new rev pw for {}", tunnelId);
+                lamdaResult = deployPseudoWire(
+                        newPw.l2Tunnel(),
+                        newPw.l2TunnelPolicy().cP2(),
+                        newPw.l2TunnelPolicy().cP1(),
+                        REV
+                );
+                if (lamdaResult != SUCCESS) {
+                    return;
+                }
+                lamdaResult = deployPolicy(
+                        tunnelId,
+                        newPw.l2TunnelPolicy().cP2(),
+                        newPw.l2TunnelPolicy().cP2InnerTag(),
+                        newPw.l2TunnelPolicy().cP2OuterTag(),
+                        lamdaResult.nextId
+                );
+            }
         });
     }
 
@@ -68,9 +350,685 @@
      */
     public void processPwaasConfigRemoved(NetworkConfigEvent event) {
         log.info("Processing Pwaas CONFIG_REMOVED");
-        PwaasConfig config = (PwaasConfig) event.config().get();
-        config.getPwIds().forEach(pwId -> {
-            log.info("{}", config.getPwDescription(pwId));
-        });
+        PwaasConfig config = (PwaasConfig) event.prevConfig().get();
+        Set<DefaultL2TunnelDescription> pwToRemove = config.getPwIds()
+                .stream()
+                .map(config::getPwDescription)
+                .collect(Collectors.toSet());
+        // We teardown all the pseudo wire deployed
+        tearDown(pwToRemove);
     }
+
+    /**
+     * Helper function to handle the pw removal.
+     *
+     * @param pwToRemove the pseudo wires to remove
+     */
+    private void tearDown(Set<DefaultL2TunnelDescription> pwToRemove) {
+        Result result;
+        int nextId;
+        NextObjective nextObjective;
+        long l2TunnelId;
+        // We remove all the pw in the configuration
+        // file.
+        for (DefaultL2TunnelDescription currentL2Tunnel : pwToRemove) {
+            l2TunnelId = currentL2Tunnel.l2Tunnel().tunnelId();
+            if (l2TunnelId == 0) {
+                log.warn("Tunnel id cannot be 0");
+                continue;
+            }
+            result = verifyPseudoWire(currentL2Tunnel);
+            if (result != SUCCESS) {
+                continue;
+            }
+            String key = generateKey(l2TunnelId, FWD);
+            if (!l2InitiationNextObjStore.containsKey(key)) {
+                log.warn("NextObj for {} does not exist in the store.", key);
+                continue;
+            }
+            nextObjective = l2InitiationNextObjStore.get(key).value();
+            nextId = nextObjective.id();
+            // First all we have to delete the policy.
+            deletePolicy(
+                    l2TunnelId,
+                    currentL2Tunnel.l2TunnelPolicy().cP1(),
+                    currentL2Tunnel.l2TunnelPolicy().cP1InnerTag(),
+                    currentL2Tunnel.l2TunnelPolicy().cP1OuterTag(),
+                    nextId,
+                    null
+            );
+            // Finally we will tear down the pseudo wire.
+            tearDownPseudoWire(
+                    key,
+                    nextObjective,
+                    currentL2Tunnel.l2TunnelPolicy().cP1(),
+                    currentL2Tunnel.l2TunnelPolicy().cP2(),
+                    null
+            );
+            // We do the same operations on the reverse side.
+            key = generateKey(l2TunnelId, REV);
+            if (!l2InitiationNextObjStore.containsKey(key)) {
+                log.warn("NextObj for {} does not exist in the store.", key);
+                continue;
+            }
+            nextObjective = l2InitiationNextObjStore.get(key).value();
+            nextId = nextObjective.id();
+            deletePolicy(
+                    l2TunnelId,
+                    currentL2Tunnel.l2TunnelPolicy().cP2(),
+                    currentL2Tunnel.l2TunnelPolicy().cP2InnerTag(),
+                    currentL2Tunnel.l2TunnelPolicy().cP2OuterTag(),
+                    nextId,
+                    null
+            );
+            tearDownPseudoWire(
+                    key,
+                    nextObjective,
+                    currentL2Tunnel.l2TunnelPolicy().cP2(),
+                    currentL2Tunnel.l2TunnelPolicy().cP1(),
+                    null
+            );
+        }
+
+    }
+
+    /**
+     * Helper method to verify the integrity of the pseudo wire.
+     *
+     * @param l2TunnelDescription the pseudo wire description
+     * @return the result of the check
+     */
+    private Result verifyPseudoWire(DefaultL2TunnelDescription l2TunnelDescription) {
+        Result result;
+        DefaultL2Tunnel l2Tunnel = l2TunnelDescription.l2Tunnel();
+        DefaultL2TunnelPolicy l2TunnelPolicy = l2TunnelDescription.l2TunnelPolicy();
+        result = verifyTunnel(l2Tunnel);
+        if (result != SUCCESS) {
+            log.warn("Tunnel {} did not pass the validation", l2Tunnel.tunnelId());
+            return result;
+        }
+        result = verifyPolicy(
+                l2TunnelPolicy.isAllVlan(),
+                l2TunnelPolicy.cP1InnerTag(),
+                l2TunnelPolicy.cP1OuterTag(),
+                l2TunnelPolicy.cP2InnerTag(),
+                l2TunnelPolicy.cP2OuterTag()
+        );
+        if (result != SUCCESS) {
+            log.warn("Policy for tunnel {} did not pass the validation", l2Tunnel.tunnelId());
+            return result;
+        }
+
+        return SUCCESS;
+    }
+
+    /**
+     * TODO Operation on the policies store.
+     *
+     * Handles the policy establishment which consists in
+     * create the filtering and forwarding objectives related
+     * to the initiation and termination.
+     *
+     * @param tunnelId the tunnel id
+     * @param ingress the ingress point
+     * @param ingressInner the ingress inner tag
+     * @param ingressOuter the ingress outer tag
+     * @param nextId the next objective id
+     * @return SUCCESS if the policy has been deployed.
+     * Otherwise an error according to the failure
+     * scenario.
+     */
+    private Result deployPolicy(long tunnelId,
+                                ConnectPoint ingress,
+                                VlanId ingressInner,
+                                VlanId ingressOuter,
+                                int nextId) {
+
+        ForwardingObjective.Builder fwdBuilder;
+        FilteringObjective.Builder filtBuilder;
+        List<Objective> objectives = Lists.newArrayList();
+        if (!srManager.mastershipService.isLocalMaster(ingress.deviceId())) {
+            log.info("Abort creation of policy for L2 tunnel {}: {}", tunnelId, NOT_MASTER);
+            return SUCCESS;
+        }
+        // We create the forwarding objective for supporting
+        // the l2 tunnel.
+        fwdBuilder = createFwdObjective(
+                INITIATION,
+                tunnelId,
+                ingress.port(),
+                nextId
+        );
+        // We create and add objective context.
+        ObjectiveContext context = new DefaultObjectiveContext(
+                (objective)
+                        -> log.debug("FwdObj for tunnel {} populated", tunnelId),
+                (objective, error)
+                        -> log.warn("Failed to populate fwdrObj for tunnel {}", tunnelId, error));
+        objectives.add(fwdBuilder.add(context));
+        // We create the filtering objective to define the
+        // permit traffic in the switch
+        filtBuilder = createFiltObjective(
+                ingress.port(),
+                ingressInner,
+                ingressOuter
+        );
+        // We add the metadata.
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder()
+                .setTunnelId(tunnelId);
+        filtBuilder.withMeta(treatment.build());
+        // We create and add objective context.
+        context = new DefaultObjectiveContext(
+                (objective)
+                        -> log.debug("FilterObj for tunnel {} populated", tunnelId),
+                (objective, error)
+                        -> log.warn("Failed to populate filterObj for tunnel {}", tunnelId, error));
+        objectives.add(filtBuilder.add(context));
+
+        for (Objective objective : objectives) {
+            if (objective instanceof ForwardingObjective) {
+                srManager.flowObjectiveService.forward(ingress.deviceId(), (ForwardingObjective) objective);
+                log.debug("Creating new FwdObj for NextObj with id={} for tunnel {}", nextId, tunnelId);
+            } else {
+                srManager.flowObjectiveService.filter(ingress.deviceId(), (FilteringObjective) objective);
+                log.debug("Creating new FiltObj for tunnel {}", tunnelId);
+            }
+        }
+        return SUCCESS;
+    }
+
+    /**
+     * Helper method to verify if the policy is whether or not
+     * supported.
+     *
+     * @param isAllVlan all vlan mode
+     * @param ingressInner the ingress inner tag
+     * @param ingressOuter the ingress outer tag
+     * @param egressInner the egress inner tag
+     * @param egressOuter the egress outer tag
+     * @return the result of verification
+     */
+    private Result verifyPolicy(boolean isAllVlan,
+                                VlanId ingressInner,
+                                VlanId ingressOuter,
+                                VlanId egressInner,
+                                VlanId egressOuter) {
+        // AllVlan mode is not supported yet.
+        if (isAllVlan) {
+            log.warn("AllVlan not supported yet");
+            return UNSUPPORTED;
+        }
+        // The vlan tags for cP1 and cP2 have to be different from
+        // vlan none.
+        if (ingressInner.equals(VlanId.NONE) ||
+                ingressOuter.equals(VlanId.NONE) ||
+                egressInner.equals(VlanId.NONE) ||
+                egressOuter.equals(VlanId.NONE)) {
+            log.warn("The vlan tags for the connect point have to be" +
+                             "different from vlan none");
+            return WRONG_PARAMETERS;
+        }
+        return SUCCESS;
+    }
+
+    /**
+     * TODO Operation on the policies store.
+     *
+     * Handles the tunnel establishment which consists in
+     * create the next objectives related to the initiation
+     * and termination.
+     *
+     * @param l2Tunnel the tunnel to deploy
+     * @param ingress the ingress connect point
+     * @param egress the egress connect point
+     * @param direction the direction of the pw
+     * @return SUCCESS if the tunnel has been created.
+     * Otherwise an error according to the failure
+     * scenario
+     */
+    private Result deployPseudoWire(DefaultL2Tunnel l2Tunnel,
+                                    ConnectPoint ingress,
+                                    ConnectPoint egress,
+                                    String direction) {
+        Link nextHop;
+        NextObjective.Builder nextObjectiveBuilder;
+        NextObjective nextObjective;
+        int nextId;
+        Result result;
+        if (!srManager.mastershipService.isLocalMaster(ingress.deviceId())) {
+            log.info("Abort initiation creation of L2 tunnel {}: {}",
+                     l2Tunnel.tunnelId(), NOT_MASTER);
+            return SUCCESS;
+        }
+        // We need at least a path between ingress and egress.
+        nextHop = getNextHop(ingress, egress);
+        if (nextHop == null) {
+            log.warn("No path between ingress and egress");
+            return WRONG_PARAMETERS;
+        }
+        // We create the next objective without the metadata
+        // context and id. We check if it already exists in the
+        // store. If not we store as it is in the store ?
+        nextObjectiveBuilder = createNextObjective(
+                INITIATION,
+                nextHop,
+                l2Tunnel,
+                egress.deviceId()
+        );
+        if (nextObjectiveBuilder == null) {
+            return INTERNAL_ERROR;
+        }
+        // We set the metadata. We will use this metadata
+        // to inform the driver we are doing a l2 tunnel.
+        TrafficSelector metadata = DefaultTrafficSelector
+                .builder()
+                .matchTunnelId(l2Tunnel.tunnelId())
+                .build();
+        nextObjectiveBuilder.withMeta(metadata);
+        nextId = srManager.flowObjectiveService.allocateNextId();
+        if (nextId < 0) {
+            log.warn("Not able to allocate a next id for initiation");
+            return INTERNAL_ERROR;
+        }
+        nextObjectiveBuilder.withId(nextId);
+        String key = generateKey(l2Tunnel.tunnelId(), direction);
+        l2InitiationNextObjStore.put(key, nextObjectiveBuilder.add());
+        ObjectiveContext context = new DefaultObjectiveContext(
+                (objective)
+                        -> log.debug("Initiation l2 tunnel rule for {} populated",
+                                     l2Tunnel.tunnelId()),
+                (objective, error)
+                        -> log.warn("Failed to populate Initiation l2 tunnel rule for {}: {}",
+                                    l2Tunnel.tunnelId(), error));
+        nextObjective = nextObjectiveBuilder.add(context);
+        srManager.flowObjectiveService.next(ingress.deviceId(), nextObjective);
+        log.debug("Initiation next objective for {} not found. Creating new NextObj with id={}",
+                  l2Tunnel.tunnelId(),
+                  nextObjective.id()
+        );
+        result = SUCCESS;
+        result.nextId = nextObjective.id();
+        return result;
+    }
+
+    /**
+     * Helper method to verify if the tunnel is whether or not
+     * supported.
+     *
+     * @param l2Tunnel the tunnel to verify
+     * @return the result of the verification
+     */
+    private Result verifyTunnel(DefaultL2Tunnel l2Tunnel) {
+        // Service delimiting tag not supported yet.
+        if (!l2Tunnel.sdTag().equals(VlanId.NONE)) {
+            log.warn("Service delimiting tag not supported yet");
+            return UNSUPPORTED;
+        }
+        // Tag mode not supported yet.
+        if (l2Tunnel.pwMode() == TAGGED) {
+            log.warn("Tagged mode not supported yet");
+            return UNSUPPORTED;
+        }
+        // Raw mode without service delimiting tag
+        // is the only mode supported for now.
+        return SUCCESS;
+    }
+
+    /**
+     * Create the filtering objective according to a given policy.
+     *
+     * @param inPort the in port
+     * @param innerTag the inner vlan tag
+     * @param outerTag the outer vlan tag
+     * @return the filtering objective
+     */
+    private FilteringObjective.Builder createFiltObjective(PortNumber inPort,
+                                                           VlanId innerTag,
+                                                           VlanId outerTag) {
+        return DefaultFilteringObjective.builder()
+                .withKey(Criteria.matchInPort(inPort))
+                .addCondition(Criteria.matchInnerVlanId(innerTag))
+                .addCondition(Criteria.matchVlanId(outerTag))
+                .withPriority(SegmentRoutingService.DEFAULT_PRIORITY)
+                .permit()
+                .fromApp(srManager.appId);
+    }
+
+    /**
+     * Create the forwarding objective according to a given pipeline.
+     *
+     * @param pipeline the pipeline
+     * @param tunnelId the tunnel id
+     * @param nextId the next step
+     * @return the forwarding objective to support the pipeline.
+     */
+    private ForwardingObjective.Builder createFwdObjective(Pipeline pipeline,
+                                                           long tunnelId,
+                                                           PortNumber inPort,
+                                                           int nextId) {
+        ForwardingObjective.Builder fwdBuilder = null;
+        TrafficSelector.Builder trafficSelector = DefaultTrafficSelector
+                .builder();
+        if (pipeline == INITIATION) {
+            // The flow has to match on the mpls logical
+            // port and the tunnel id.
+            trafficSelector.matchTunnelId(tunnelId);
+            trafficSelector.matchInPort(inPort);
+            fwdBuilder = DefaultForwardingObjective.builder()
+                    .fromApp(srManager.appId)
+                    .makePermanent()
+                    .nextStep(nextId)
+                    .withPriority(SegmentRoutingService.DEFAULT_PRIORITY)
+                    .withSelector(trafficSelector.build())
+                    .withFlag(VERSATILE);
+        }
+        return fwdBuilder;
+
+    }
+
+    /**
+     * Creates the next objective according to a given
+     * pipeline. We don't set the next id and we don't
+     * create the final meta to check if we are re-using
+     * the same next objective for different tunnels.
+     *
+     * @param pipeline the pipeline to support
+     * @param nextHop the next hop towards the destination
+     * @param l2Tunnel the tunnel to support
+     * @param egressId the egress device id
+     * @return the next objective to support the pipeline
+     */
+    private NextObjective.Builder createNextObjective(Pipeline pipeline,
+                                                      Link nextHop,
+                                                      DefaultL2Tunnel l2Tunnel,
+                                                      DeviceId egressId) {
+        NextObjective.Builder nextObjBuilder;
+        TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
+        if (pipeline == INITIATION) {
+            nextObjBuilder = DefaultNextObjective
+                    .builder()
+                    .withType(NextObjective.Type.SIMPLE)
+                    .fromApp(srManager.appId);
+            // The pw label is the bottom of stack. It has to
+            // be different -1.
+            if (l2Tunnel.pwLabel().toInt() == MplsLabel.MAX_MPLS) {
+                log.warn("Pw label not configured");
+                return null;
+            }
+            treatmentBuilder.pushMpls();
+            treatmentBuilder.setMpls(l2Tunnel.pwLabel());
+            treatmentBuilder.setMplsBos(true);
+            treatmentBuilder.copyTtlOut();
+            // If the inter-co label is present we have to set the label.
+            if (l2Tunnel.interCoLabel().toInt() != MplsLabel.MAX_MPLS) {
+                treatmentBuilder.pushMpls();
+                treatmentBuilder.setMpls(l2Tunnel.interCoLabel());
+                treatmentBuilder.setMplsBos(false);
+                treatmentBuilder.copyTtlOut();
+            }
+            // We retrieve the sr label from the config
+            // using the egress leaf device id.
+            MplsLabel srLabel;
+            try {
+                 srLabel = MplsLabel.mplsLabel(
+                         srManager.deviceConfiguration.getIPv4SegmentId(egressId)
+                 );
+            } catch (DeviceConfigNotFoundException e) {
+                log.warn("Sr label not configured");
+                return null;
+            }
+            treatmentBuilder.pushMpls();
+            treatmentBuilder.setMpls(srLabel);
+            treatmentBuilder.setMplsBos(false);
+            treatmentBuilder.copyTtlOut();
+            // We have to rewrite the src and dst mac address.
+            MacAddress ingressMac;
+            try {
+                ingressMac = srManager
+                        .deviceConfiguration
+                        .getDeviceMac(nextHop.src().deviceId());
+            } catch (DeviceConfigNotFoundException e) {
+                log.warn("Was not able to find the ingress mac");
+                return null;
+            }
+            treatmentBuilder.setEthSrc(ingressMac);
+            MacAddress neighborMac;
+            try {
+                neighborMac = srManager
+                        .deviceConfiguration
+                        .getDeviceMac(nextHop.dst().deviceId());
+            } catch (DeviceConfigNotFoundException e) {
+                log.warn("Was not able to find the neighbor mac");
+                return null;
+            }
+            treatmentBuilder.setEthDst(neighborMac);
+        } else {
+            nextObjBuilder = DefaultNextObjective
+                    .builder()
+                    .withType(NextObjective.Type.SIMPLE)
+                    .fromApp(srManager.appId);
+
+        }
+        treatmentBuilder.setOutput(nextHop.src().port());
+        nextObjBuilder.addTreatment(treatmentBuilder.build());
+        return nextObjBuilder;
+    }
+
+    /**
+     * Returns the next hop.
+     *
+     * @param srcCp the ingress connect point
+     * @param dstCp the egress connect point
+     * @return the next hop
+     */
+    private Link getNextHop(ConnectPoint srcCp, ConnectPoint dstCp) {
+        // We retrieve a set of disjoint paths.
+        Set<DisjointPath> paths = srManager.pathService.getDisjointPaths(
+                srcCp.elementId(),
+                dstCp.elementId()
+        );
+        // We randmly pick a path.
+        if (paths.isEmpty()) {
+            return null;
+        }
+        int size = paths.size();
+        int index = RandomUtils.nextInt(0, size);
+        // We verify if the path is ok and there is not
+        // a misconfiguration.
+        List<Link> links = Iterables.get(paths, index).links();
+        checkState(links.size() == 2, WRONG_TOPOLOGY, links);
+        return links.get(0);
+    }
+
+    /**
+     * TODO Operation on the store.
+     * Deletes a given policy using the parameter supplied.
+     *
+     * @param tunnelId the tunnel id
+     * @param ingress the ingress point
+     * @param ingressInner the ingress inner vlan id
+     * @param ingressOuter the ingress outer vlan id
+     * @param nextId the next objective id
+     */
+    private void deletePolicy(long tunnelId,
+                              ConnectPoint ingress,
+                              VlanId ingressInner,
+                              VlanId ingressOuter,
+                              int nextId,
+                              CompletableFuture<ObjectiveError> fwdFuture) {
+
+        ForwardingObjective.Builder fwdBuilder;
+        FilteringObjective.Builder filtBuilder;
+        List<Objective> objectives = Lists.newArrayList();
+        if (!srManager.mastershipService.isLocalMaster(ingress.deviceId())) {
+            log.info("Abort delete of policy for L2 tunnel {}: {}", tunnelId, NOT_MASTER);
+            return;
+        }
+        // We create the forwarding objective.
+        fwdBuilder = createFwdObjective(
+                INITIATION,
+                tunnelId,
+                ingress.port(),
+                nextId
+        );
+        ObjectiveContext context = new ObjectiveContext() {
+            @Override
+            public void onSuccess(Objective objective) {
+                log.debug("Previous FwdObj for policy {} removed", tunnelId);
+                if (fwdFuture != null) {
+                    fwdFuture.complete(null);
+                }
+            }
+
+            @Override
+            public void onError(Objective objective, ObjectiveError error) {
+                log.warn("Failed to remove previous FwdObj for policy {}: {}", tunnelId, error);
+                if (fwdFuture != null) {
+                    fwdFuture.complete(error);
+                }
+            }
+        };
+        objectives.add(fwdBuilder.remove(context));
+        // We create the filtering objective to define the
+        // permit traffic in the switch
+        filtBuilder = createFiltObjective(
+                ingress.port(),
+                ingressInner,
+                ingressOuter
+        );
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder()
+                .setTunnelId(tunnelId);
+        filtBuilder.withMeta(treatment.build());
+        context = new DefaultObjectiveContext(
+                (objective)
+                        -> log.debug("FilterObj for policy {} revoked", tunnelId),
+                (objective, error)
+                        -> log.warn("Failed to revoke filterObj for policy {}", tunnelId, error));
+        objectives.add(filtBuilder.remove(context));
+
+        for (Objective objective : objectives) {
+            if (objective instanceof ForwardingObjective) {
+                srManager.flowObjectiveService.forward(ingress.deviceId(), (ForwardingObjective) objective);
+            } else {
+                srManager.flowObjectiveService.filter(ingress.deviceId(), (FilteringObjective) objective);
+            }
+        }
+    }
+
+    /**
+     * TODO Operation on the store.
+     * Deletes a given pseudo wire using the parameter supplied.
+     *
+     * @param key the key of the store
+     * @param nextObjective the next objective representing the pw
+     * @param ingress the ingress connect point
+     * @param egress the egress connect point
+     */
+    private void tearDownPseudoWire(String key,
+                                    NextObjective nextObjective,
+                                    ConnectPoint ingress,
+                                    ConnectPoint egress,
+                                    CompletableFuture<ObjectiveError> nextFutureForInit) {
+        if (!srManager.mastershipService.isLocalMaster(ingress.deviceId())) {
+            log.info("Abort delete of {} for {}: {}", INITIATION, key, NOT_MASTER);
+            return;
+        }
+        ObjectiveContext context = new ObjectiveContext() {
+            @Override
+            public void onSuccess(Objective objective) {
+                log.debug("Previous {} NextObj for {} removed", INITIATION, key);
+                if (nextFutureForInit != null) {
+                    nextFutureForInit.complete(null);
+                }
+            }
+
+            @Override
+            public void onError(Objective objective, ObjectiveError error) {
+                log.warn("Failed to remove previous {} NextObj for {}: {}", INITIATION, key, error);
+                if (nextFutureForInit != null) {
+                    nextFutureForInit.complete(error);
+                }
+            }
+        };
+        srManager.flowObjectiveService.next(
+                ingress.deviceId(),
+                (NextObjective) nextObjective.copy().remove(context)
+        );
+        l2InitiationNextObjStore.remove(key);
+    }
+
+    /**
+     * Utilities to generate pw key.
+     *
+     * @param tunnelId the tunnel id
+     * @param direction the direction of the pw
+     * @return the key of the store
+     */
+    private String generateKey(long tunnelId, String direction) {
+        return String.format("%s-%s", tunnelId, direction);
+    }
+
+    /**
+     * VPWS pipelines.
+     */
+    protected enum Pipeline {
+        /**
+         * The initiation pipeline.
+         */
+        INITIATION,
+        /**
+         * The termination pipeline.
+         */
+        TERMINATION;
+    }
+
+    /**
+     * Enum helper to carry the outcomes of an operation.
+     */
+    public enum Result {
+        /**
+         * Happy ending scenario it has been created.
+         */
+        SUCCESS(0, "It has been Created"),
+        /**
+         * We have problems with the supplied parameters.
+         */
+        WRONG_PARAMETERS(1, "Wrong parameters"),
+        /**
+         * It already exists.
+         */
+        ID_EXISTS(2, "The id already exists"),
+        /**
+         * We have an internal error during the deployment
+         * phase.
+         */
+        INTERNAL_ERROR(3, "Internal error"),
+        /**
+         * The operation is not supported.
+         */
+        UNSUPPORTED(4, "Unsupported");
+
+        private final int code;
+        private final String description;
+        private int nextId;
+
+        private Result(int code, String description) {
+            this.code = code;
+            this.description = description;
+        }
+
+        public String getDescription() {
+            return description;
+        }
+
+        public int getCode() {
+            return code;
+        }
+
+        @Override
+        public String toString() {
+            return code + ": " + description;
+        }
+    }
+
 }
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa2GroupHandler.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa2GroupHandler.java
index 2a4de98..9e3161a 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa2GroupHandler.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa2GroupHandler.java
@@ -37,6 +37,7 @@
 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.TunnelIdCriterion;
 import org.onosproject.net.flow.criteria.VlanIdCriterion;
 import org.onosproject.net.flow.instructions.Instruction;
 import org.onosproject.net.flow.instructions.Instructions;
@@ -80,6 +81,7 @@
 import static org.onosproject.driver.pipeline.Ofdpa2GroupHandler.OfdpaMplsGroupSubType.OFDPA_GROUP_TYPE_SHIFT;
 import static org.onosproject.driver.pipeline.Ofdpa2GroupHandler.OfdpaMplsGroupSubType.OFDPA_MPLS_SUBTYPE_SHIFT;
 import static org.onosproject.driver.pipeline.Ofdpa2Pipeline.isNotMplsBos;
+import static org.onosproject.net.flow.criteria.Criterion.Type.TUNNEL_ID;
 import static org.onosproject.net.flow.criteria.Criterion.Type.VLAN_VID;
 import static org.onosproject.net.flowobjective.NextObjective.Type.HASHED;
 import static org.slf4j.LoggerFactory.getLogger;
@@ -284,32 +286,50 @@
         }
 
         boolean isMpls = false;
+        // In order to understand if it is a pseudo wire related
+        // next objective we look for the tunnel id in the meta.
+        boolean isPw = false;
         if (nextObj.meta() != null) {
             isMpls = isNotMplsBos(nextObj.meta());
+
+            TunnelIdCriterion tunnelIdCriterion = (TunnelIdCriterion) nextObj
+                    .meta()
+                    .getCriterion(TUNNEL_ID);
+            if (tunnelIdCriterion != null) {
+                isPw = true;
+            }
+
         }
 
-        // break up simple next objective to GroupChain objects
-        GroupInfo groupInfo = createL2L3Chain(treatment, nextObj.id(),
-                                              nextObj.appId(), isMpls,
-                                              nextObj.meta());
-        if (groupInfo == null) {
-            log.error("Could not process nextObj={} in dev:{}", nextObj.id(), deviceId);
-            return;
+        if (!isPw) {
+            // break up simple next objective to GroupChain objects
+            GroupInfo groupInfo = createL2L3Chain(treatment, nextObj.id(),
+                                                  nextObj.appId(), isMpls,
+                                                  nextObj.meta());
+            if (groupInfo == null) {
+                log.error("Could not process nextObj={} in dev:{}", nextObj.id(), deviceId);
+                return;
+            }
+            // create object for local and distributed storage
+            Deque<GroupKey> gkeyChain = new ArrayDeque<>();
+            gkeyChain.addFirst(groupInfo.innerMostGroupDesc.appCookie());
+            gkeyChain.addFirst(groupInfo.nextGroupDesc.appCookie());
+            OfdpaNextGroup ofdpaGrp =
+                    new OfdpaNextGroup(Collections.singletonList(gkeyChain), nextObj);
+
+            // store l3groupkey with the ofdpaNextGroup for the nextObjective that depends on it
+            updatePendingNextObjective(groupInfo.nextGroupDesc.appCookie(), ofdpaGrp);
+
+            // now we are ready to send the l2 groupDescription (inner), as all the stores
+            // that will get async replies have been updated. By waiting to update
+            // the stores, we prevent nasty race conditions.
+            groupService.addGroup(groupInfo.innerMostGroupDesc);
+        } else {
+            // We handle the pseudo wire with a different a procedure.
+            // This procedure is meant to handle both initiation and
+            // termination of the pseudo wire.
+            processPwNextObjective(nextObj);
         }
-        // create object for local and distributed storage
-        Deque<GroupKey> gkeyChain = new ArrayDeque<>();
-        gkeyChain.addFirst(groupInfo.innerMostGroupDesc.appCookie());
-        gkeyChain.addFirst(groupInfo.nextGroupDesc.appCookie());
-        OfdpaNextGroup ofdpaGrp =
-                new OfdpaNextGroup(Collections.singletonList(gkeyChain), nextObj);
-
-        // store l3groupkey with the ofdpaNextGroup for the nextObjective that depends on it
-        updatePendingNextObjective(groupInfo.nextGroupDesc.appCookie(), ofdpaGrp);
-
-        // now we are ready to send the l2 groupDescription (inner), as all the stores
-        // that will get async replies have been updated. By waiting to update
-        // the stores, we prevent nasty race conditions.
-        groupService.addGroup(groupInfo.innerMostGroupDesc);
     }
 
     /**
@@ -387,8 +407,8 @@
      *         error in processing the chain
      */
     protected GroupInfo createL2L3ChainInternal(TrafficTreatment treatment, int nextId,
-                                      ApplicationId appId, boolean mpls,
-                                      TrafficSelector meta, boolean useSetVlanExtension) {
+                                                ApplicationId appId, boolean mpls,
+                                                TrafficSelector meta, boolean useSetVlanExtension) {
         // 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();
@@ -973,6 +993,18 @@
         }
     }
 
+    /**
+     * Processes the pseudo wire related next objective.
+     * This procedure try to reuse the mpls label groups,
+     * the mpls interface group and the l2 interface group.
+     *
+     * @param nextObjective the objective to process.
+     */
+    protected void processPwNextObjective(NextObjective nextObjective) {
+        log.warn("Pseudo wire extensions are not support for the OFDPA 2.0 {}", nextObjective.id());
+        return;
+    }
+
     //////////////////////////////////////
     //  Group Editing
     //////////////////////////////////////
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa2Pipeline.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa2Pipeline.java
index a49e4fa..e32f5d5 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa2Pipeline.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa2Pipeline.java
@@ -102,8 +102,12 @@
  *
  */
 public class Ofdpa2Pipeline extends AbstractHandlerBehaviour implements Pipeliner {
+
     protected static final int PORT_TABLE = 0;
     protected static final int VLAN_TABLE = 10;
+    protected static final int VLAN_1_TABLE = 11;
+    protected static final int MPLS_L2_PORT_FLOW_TABLE = 13;
+    protected static final int MPLS_L2_PORT_PCP_TRUST_FLOW_TABLE = 16;
     protected static final int TMAC_TABLE = 20;
     protected static final int UNICAST_ROUTING_TABLE = 30;
     protected static final int MULTICAST_ROUTING_TABLE = 40;
@@ -120,6 +124,11 @@
     protected static final int DEFAULT_PRIORITY = 0x8000;
     protected static final int LOWEST_PRIORITY = 0x0;
 
+    protected static final int MPLS_L2_PORT_PRIORITY = 2;
+
+    protected static final int MPLS_TUNNEL_ID_BASE = 0x10000;
+    protected static final int MPLS_TUNNEL_ID_MAX = 0x1FFFF;
+
     private final Logger log = getLogger(getClass());
     protected ServiceDirectory serviceDirectory;
     protected FlowRuleService flowRuleService;
@@ -225,6 +234,7 @@
             rules.stream()
             .filter(Objects::nonNull)
             .forEach(flowOpsBuilder::remove);
+            log.debug("Deleting a flow rule to sw:{}", deviceId);
             break;
         default:
             fail(fwd, ObjectiveError.UNKNOWN);
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa3GroupHandler.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa3GroupHandler.java
index 5ba0446..1c30333 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa3GroupHandler.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa3GroupHandler.java
@@ -16,18 +16,338 @@
 
 package org.onosproject.driver.pipeline;
 
+import com.google.common.collect.Lists;
+import org.onlab.packet.VlanId;
 import org.onosproject.core.ApplicationId;
+import org.onosproject.core.DefaultGroupId;
+import org.onosproject.driver.extensions.Ofdpa3PushCw;
+import org.onosproject.driver.extensions.Ofdpa3PushL2Header;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction;
+import org.onosproject.net.flow.instructions.L3ModificationInstruction;
+import org.onosproject.net.flowobjective.NextObjective;
+import org.onosproject.net.flowobjective.ObjectiveError;
+import org.onosproject.net.group.DefaultGroupBucket;
+import org.onosproject.net.group.DefaultGroupDescription;
+import org.onosproject.net.group.DefaultGroupKey;
+import org.onosproject.net.group.GroupBucket;
+import org.onosproject.net.group.GroupBuckets;
+import org.onosproject.net.group.GroupDescription;
+import org.onosproject.net.group.GroupKey;
+import org.slf4j.Logger;
+
+import java.util.ArrayDeque;
+import java.util.Collections;
+import java.util.Deque;
+import java.util.List;
+
+import static org.onosproject.driver.pipeline.Ofdpa2GroupHandler.OfdpaMplsGroupSubType.*;
+import static org.onosproject.net.flow.instructions.L3ModificationInstruction.L3SubType.TTL_OUT;
+import static org.onosproject.net.group.GroupDescription.Type.INDIRECT;
+import static org.slf4j.LoggerFactory.getLogger;
 
 /**
  * Group handler for OFDPA2 pipeline.
  */
 public class Ofdpa3GroupHandler extends Ofdpa2GroupHandler {
+
+    private static final int PW_INTERNAL_VLAN = 4094;
+    private static final int MAX_DEPTH_UNPROTECTED_PW = 3;
+
+    private final Logger log = getLogger(getClass());
+
     @Override
     protected GroupInfo createL2L3Chain(TrafficTreatment treatment, int nextId,
                                         ApplicationId appId, boolean mpls,
                                         TrafficSelector meta) {
         return createL2L3ChainInternal(treatment, nextId, appId, mpls, meta, false);
     }
+
+    @Override
+    protected void processPwNextObjective(NextObjective nextObjective) {
+        TrafficTreatment treatment = nextObjective.next().iterator().next();
+        Deque<GroupKey> gkeyChain = new ArrayDeque<>();
+        GroupChainElem groupChainElem;
+        GroupKey groupKey;
+        GroupDescription groupDescription;
+        // Now we separate the mpls actions from the l2/l3 actions
+        TrafficTreatment.Builder l2L3Treatment = DefaultTrafficTreatment.builder();
+        TrafficTreatment.Builder mplsTreatment = DefaultTrafficTreatment.builder();
+        createL2L3AndMplsTreatments(treatment, l2L3Treatment, mplsTreatment);
+        // We create the chain from mpls intf group to
+        // l2 intf group.
+        GroupInfo groupInfo = createL2L3ChainInternal(
+                l2L3Treatment.build(),
+                nextObjective.id(),
+                nextObjective.appId(),
+                true,
+                nextObjective.meta(),
+                false
+        );
+        if (groupInfo == null) {
+            log.error("Could not process nextObj={} in dev:{}", nextObjective.id(), deviceId);
+            Ofdpa2Pipeline.fail(nextObjective, ObjectiveError.GROUPINSTALLATIONFAILED);
+            return;
+        }
+        // We update the chain with the last two groups;
+        gkeyChain.addFirst(groupInfo.getInnerMostGroupDesc().appCookie());
+        gkeyChain.addFirst(groupInfo.getNextGroupDesc().appCookie());
+        // We retrieve also all mpls instructions.
+        List<List<Instruction>> mplsInstructionSets = Lists.newArrayList();
+        List<Instruction> mplsInstructionSet = Lists.newArrayList();
+        L3ModificationInstruction l3Ins;
+        for (Instruction ins : treatment.allInstructions()) {
+            // Each mpls instruction set is delimited by a
+            // copy ttl outward action.
+            mplsInstructionSet.add(ins);
+            if (ins.type() == Instruction.Type.L3MODIFICATION) {
+                l3Ins = (L3ModificationInstruction) ins;
+                if (l3Ins.subtype() == TTL_OUT) {
+                    mplsInstructionSets.add(mplsInstructionSet);
+                    mplsInstructionSet = Lists.newArrayList();
+                }
+
+            }
+        }
+        if (mplsInstructionSets.size() > MAX_DEPTH_UNPROTECTED_PW) {
+            log.error("Next Objective for pseudo wire should have at "
+                              + "most {} mpls instruction sets. Next Objective Id:{}",
+                      MAX_DEPTH_UNPROTECTED_PW, nextObjective.id());
+            Ofdpa2Pipeline.fail(nextObjective, ObjectiveError.BADPARAMS);
+            return;
+        }
+        int nextGid = groupInfo.getNextGroupDesc().givenGroupId();
+        int index;
+        // We create the mpls tunnel label groups.
+        // In this case we need to use also the
+        // tunnel label group 2;
+        if (mplsInstructionSets.size() == MAX_DEPTH_UNPROTECTED_PW) {
+            // We deal with the label 2 group.
+            index = getNextAvailableIndex();
+            groupDescription = createMplsTunnelLabelGroup(
+                    nextGid,
+                    MPLS_TUNNEL_LABEL_2,
+                    index,
+                    mplsInstructionSets.get(2),
+                    nextObjective.appId()
+            );
+            groupKey = new DefaultGroupKey(
+                    Ofdpa2Pipeline.appKryo.serialize(index)
+            );
+            // We update the chain.
+            groupChainElem = new GroupChainElem(groupDescription, 1, false);
+            updatePendingGroups(
+                    groupInfo.getNextGroupDesc().appCookie(),
+                    groupChainElem
+            );
+            gkeyChain.addFirst(groupKey);
+            // We have to create tunnel label group and
+            // l2 vpn group before to send the inner most
+            // group. We update the nextGid.
+            nextGid = groupDescription.givenGroupId();
+            groupInfo = new GroupInfo(groupInfo.getInnerMostGroupDesc(), groupDescription);
+
+            log.debug("Trying Label 2 Group: device:{} gid:{} gkey:{} nextId:{}",
+                      deviceId, Integer.toHexString(nextGid),
+                      groupKey, nextObjective.id());
+        }
+        // We deal with the label 1 group.
+        index = getNextAvailableIndex();
+        groupDescription = createMplsTunnelLabelGroup(
+                nextGid,
+                MPLS_TUNNEL_LABEL_1,
+                index,
+                mplsInstructionSets.get(1),
+                nextObjective.appId()
+        );
+        groupKey = new DefaultGroupKey(
+                Ofdpa2Pipeline.appKryo.serialize(index)
+        );
+        groupChainElem = new GroupChainElem(groupDescription, 1, false);
+        updatePendingGroups(
+                groupInfo.getNextGroupDesc().appCookie(),
+                groupChainElem
+        );
+        gkeyChain.addFirst(groupKey);
+        // We have to create the l2 vpn group before
+        // to send the inner most group.
+        nextGid = groupDescription.givenGroupId();
+        groupInfo = new GroupInfo(groupInfo.getInnerMostGroupDesc(), groupDescription);
+
+        log.debug("Trying Label 1 Group: device:{} gid:{} gkey:{} nextId:{}",
+                  deviceId, Integer.toHexString(nextGid),
+                  groupKey, nextObjective.id());
+        // Finally we create the l2 vpn group.
+        index = getNextAvailableIndex();
+        groupDescription = createMplsL2VpnGroup(
+                nextGid,
+                index,
+                mplsInstructionSets.get(0),
+                nextObjective.appId()
+        );
+        groupKey = new DefaultGroupKey(
+                Ofdpa2Pipeline.appKryo.serialize(index)
+        );
+        groupChainElem = new GroupChainElem(groupDescription, 1, false);
+        updatePendingGroups(
+                groupInfo.getNextGroupDesc().appCookie(),
+                groupChainElem
+        );
+        gkeyChain.addFirst(groupKey);
+        OfdpaNextGroup ofdpaGrp = new OfdpaNextGroup(
+                Collections.singletonList(gkeyChain),
+                nextObjective
+        );
+        updatePendingNextObjective(groupKey, ofdpaGrp);
+
+        log.debug("Trying L2 Vpn Group: device:{} gid:{} gkey:{} nextId:{}",
+                  deviceId, Integer.toHexString(nextGid),
+                  groupKey, nextObjective.id());
+        // Finally we send the innermost group.
+        log.debug("Sending innermost group {} in group chain on device {} ",
+                  Integer.toHexString(groupInfo.getInnerMostGroupDesc().givenGroupId()), deviceId);
+        groupService.addGroup(groupInfo.getInnerMostGroupDesc());
+    }
+
+    /**
+     * Helper method to create a mpls tunnel label group.
+     *
+     * @param nextGroupId the next group in the chain
+     * @param subtype the mpls tunnel label group subtype
+     * @param index the index of the group
+     * @param instructions the instructions to push
+     * @param applicationId the application id
+     * @return the group description
+     */
+    private GroupDescription createMplsTunnelLabelGroup(int nextGroupId,
+                                                          OfdpaMplsGroupSubType subtype,
+                                                          int index,
+                                                          List<Instruction> instructions,
+                                                          ApplicationId applicationId) {
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+        // We add all the instructions.
+        instructions.forEach(treatment::add);
+        // We point the group to the next group.
+        treatment.group(new DefaultGroupId(nextGroupId));
+        GroupBucket groupBucket = DefaultGroupBucket
+                .createIndirectGroupBucket(treatment.build());
+        // Finally we build the group description.
+        int groupId = makeMplsLabelGroupId(subtype, index);
+        GroupKey groupKey = new DefaultGroupKey(
+                Ofdpa2Pipeline.appKryo.serialize(index)
+        );
+        return new DefaultGroupDescription(
+                deviceId,
+                INDIRECT,
+                new GroupBuckets(Collections.singletonList(groupBucket)),
+                groupKey,
+                groupId,
+                applicationId
+        );
+    }
+
+    /**
+     * Helper method to create a mpls l2 vpn group.
+     *
+     * @param nextGroupId the next group in the chain
+     * @param index the index of the group
+     * @param instructions the instructions to push
+     * @param applicationId the application id
+     * @return the group description
+     */
+    private GroupDescription createMplsL2VpnGroup(int nextGroupId,
+                                                    int index,
+                                                    List<Instruction> instructions,
+                                                    ApplicationId applicationId) {
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+        // We add the extensions and the instructions.
+        treatment.extension(new Ofdpa3PushL2Header(), deviceId);
+        treatment.pushVlan();
+        instructions.forEach(treatment::add);
+        treatment.extension(new Ofdpa3PushCw(), deviceId);
+        // We point the group to the next group.
+        treatment.group(new DefaultGroupId(nextGroupId));
+        GroupBucket groupBucket = DefaultGroupBucket
+                .createIndirectGroupBucket(treatment.build());
+        // Finally we build the group description.
+        int groupId = makeMplsLabelGroupId(L2_VPN, index);
+        GroupKey groupKey = new DefaultGroupKey(
+                Ofdpa2Pipeline.appKryo.serialize(index)
+        );
+        return new DefaultGroupDescription(
+                deviceId,
+                INDIRECT,
+                new GroupBuckets(Collections.singletonList(groupBucket)),
+                groupKey,
+                groupId,
+                applicationId
+        );
+    }
+
+    /**
+     * Helper method for dividing the l2/l3 instructions from the mpls
+     * instructions.
+     *
+     * @param treatment the treatment to analyze
+     * @param l2L3Treatment the l2/l3 treatment builder
+     * @param mplsTreatment the mpls treatment builder
+     */
+    private void createL2L3AndMplsTreatments(TrafficTreatment treatment,
+                                               TrafficTreatment.Builder l2L3Treatment,
+                                               TrafficTreatment.Builder mplsTreatment) {
+
+        for (Instruction ins : treatment.allInstructions()) {
+
+            if (ins.type() == Instruction.Type.L2MODIFICATION) {
+                L2ModificationInstruction l2ins = (L2ModificationInstruction) ins;
+                switch (l2ins.subtype()) {
+                    // These instructions have to go in the l2/l3 treatment.
+                    case ETH_DST:
+                    case ETH_SRC:
+                    case VLAN_ID:
+                    case VLAN_POP:
+                        l2L3Treatment.add(ins);
+                        break;
+                    // These instructions have to go in the mpls treatment.
+                    case MPLS_BOS:
+                    case DEC_MPLS_TTL:
+                    case MPLS_LABEL:
+                    case MPLS_PUSH:
+                        mplsTreatment.add(ins);
+                        break;
+                    default:
+                        log.warn("Driver does not handle this type of TrafficTreatment"
+                                         + " instruction in nextObjectives: {} - {}",
+                                 ins.type(), ins);
+                        break;
+                }
+            } else if (ins.type() == Instruction.Type.OUTPUT) {
+                // The output goes in the l2/l3 treatment.
+                l2L3Treatment.add(ins);
+            } else if (ins.type() == Instruction.Type.L3MODIFICATION) {
+                 // We support partially the l3 instructions.
+                L3ModificationInstruction l3ins = (L3ModificationInstruction) ins;
+                switch (l3ins.subtype()) {
+                    case TTL_OUT:
+                        mplsTreatment.add(ins);
+                        break;
+                    default:
+                        log.warn("Driver does not handle this type of TrafficTreatment"
+                                         + " instruction in nextObjectives: {} - {}",
+                                 ins.type(), ins);
+                }
+
+            } else {
+                log.warn("Driver does not handle this type of TrafficTreatment"
+                                 + " instruction in nextObjectives: {} - {}",
+                         ins.type(), ins);
+            }
+        }
+        // We add in a transparent way the set vlan to 4094.
+        l2L3Treatment.setVlanId(VlanId.vlanId((short) PW_INTERNAL_VLAN));
+    }
+    // TODO Introduce in the future an inner class to return two treatments
 }
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa3Pipeline.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa3Pipeline.java
index 895c187..38fe384 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa3Pipeline.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa3Pipeline.java
@@ -16,21 +16,57 @@
 
 package org.onosproject.driver.pipeline;
 
+import com.google.common.collect.ImmutableList;
 import org.onlab.packet.VlanId;
 import org.onosproject.core.ApplicationId;
+import org.onosproject.driver.extensions.Ofdpa3MatchMplsL2Port;
+import org.onosproject.driver.extensions.Ofdpa3MatchOvid;
+import org.onosproject.driver.extensions.Ofdpa3SetMplsL2Port;
+import org.onosproject.driver.extensions.Ofdpa3SetMplsType;
+import org.onosproject.driver.extensions.Ofdpa3SetOvid;
+import org.onosproject.driver.extensions.Ofdpa3SetQosIndex;
+import org.onosproject.driver.extensions.OfdpaMatchVlanVid;
+import org.onosproject.net.behaviour.NextGroup;
 import org.onosproject.net.behaviour.PipelinerContext;
+import org.onosproject.net.flow.DefaultFlowRule;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
 import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.FlowRuleOperations;
+import org.onosproject.net.flow.FlowRuleOperationsContext;
+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.PortCriterion;
+import org.onosproject.net.flow.criteria.TunnelIdCriterion;
 import org.onosproject.net.flow.criteria.VlanIdCriterion;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType;
+import org.onosproject.net.flowobjective.FilteringObjective;
 import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.ObjectiveError;
+import org.onosproject.net.group.Group;
+import org.onosproject.net.group.GroupKey;
+import org.slf4j.Logger;
 
 import java.util.Collection;
+import java.util.Collections;
+import java.util.Deque;
 import java.util.List;
 
+import static org.onosproject.driver.extensions.Ofdpa3MplsType.VPWS;
+import static org.onosproject.net.flow.criteria.Criterion.Type.*;
+import static org.onosproject.net.flow.instructions.Instruction.Type.L2MODIFICATION;
+import static org.onosproject.net.flow.instructions.L2ModificationInstruction.ModTunnelIdInstruction;
+import static org.slf4j.LoggerFactory.getLogger;
+
 /**
  * Pipeliner for Broadcom OF-DPA 3.0 TTP.
  */
 public class Ofdpa3Pipeline extends Ofdpa2Pipeline {
+
+    private final Logger log = getLogger(getClass());
+
     @Override
     protected void initDriverId() {
         driverId = coreService.registerApplication(
@@ -44,6 +80,180 @@
     }
 
     @Override
+    protected void processFilter(FilteringObjective filteringObjective,
+                                 boolean install,
+                                 ApplicationId applicationId) {
+        // We are looking for inner vlan id criterion. We use this
+        // to identify the pseudo wire flows. In future we can enforce
+        // using also the tunnel id in the meta.
+        VlanIdCriterion innerVlanIdCriterion = null;
+        for (Criterion criterion : filteringObjective.conditions()) {
+            if (criterion.type() == INNER_VLAN_VID) {
+                innerVlanIdCriterion = (VlanIdCriterion) criterion;
+                break;
+            }
+        }
+        if (innerVlanIdCriterion != null) {
+            FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
+            PortCriterion portCriterion;
+            VlanIdCriterion outerVlanIdCriterion = null;
+            // We extract the expected port criterion in the key.
+            portCriterion = (PortCriterion) filteringObjective.key();
+            // We extract the outer vlan id criterion.
+            for (Criterion criterion : filteringObjective.conditions()) {
+                if (criterion.type() == VLAN_VID) {
+                    outerVlanIdCriterion = (VlanIdCriterion) criterion;
+                    break;
+                }
+            }
+            // We extract the tunnel id.
+            long tunnelId;
+            if (filteringObjective.meta() != null &&
+                    filteringObjective.meta().allInstructions().size() != 1) {
+                log.warn("Bad filtering objective from app: {}. Not"
+                                 + "processing filtering objective", applicationId);
+                fail(filteringObjective, ObjectiveError.BADPARAMS);
+                return;
+            } else if (filteringObjective.meta() != null &&
+                    filteringObjective.meta().allInstructions().size() == 1 &&
+                    filteringObjective.meta().allInstructions().get(0).type() == L2MODIFICATION) {
+                L2ModificationInstruction l2instruction = (L2ModificationInstruction)
+                        filteringObjective.meta().allInstructions().get(0);
+                if (l2instruction.subtype() != L2SubType.TUNNEL_ID) {
+                    log.warn("Bad filtering objective from app: {}. Not"
+                                     + "processing filtering objective", applicationId);
+                    fail(filteringObjective, ObjectiveError.BADPARAMS);
+                    return;
+                } else {
+                    tunnelId = ((ModTunnelIdInstruction) l2instruction).tunnelId();
+                }
+            } else {
+                log.warn("Bad filtering objective from app: {}. Not"
+                                 + "processing filtering objective", applicationId);
+                fail(filteringObjective, ObjectiveError.BADPARAMS);
+                return;
+            }
+            // Mpls tunnel ids according to the OFDPA manual have to be
+            // in the range [2^17-1, 2^16].
+            tunnelId = MPLS_TUNNEL_ID_BASE | tunnelId;
+            // Sanity check for the filtering objective.
+            if (portCriterion == null ||
+                    outerVlanIdCriterion == null ||
+                    tunnelId > MPLS_TUNNEL_ID_MAX) {
+                log.warn("Bad filtering objective from app: {}. Not"
+                                 + "processing filtering objective", applicationId);
+                fail(filteringObjective, ObjectiveError.BADPARAMS);
+                return;
+            }
+            // 0x0000XXXX is UNI interface.
+            if (portCriterion.port().toLong() > 0x0000FFFF) {
+                log.error("Filering Objective invalid logical port {}",
+                          portCriterion.port().toLong());
+                fail(filteringObjective, ObjectiveError.BADPARAMS);
+                return;
+            }
+            // We create the flows.
+            List<FlowRule> pwRules = processPwFilter(portCriterion,
+                                                     innerVlanIdCriterion,
+                                                     outerVlanIdCriterion,
+                                                     tunnelId,
+                                                     applicationId
+            );
+            // We tag the flow for adding or for removing.
+            for (FlowRule pwRule : pwRules) {
+                log.debug("adding filtering rule in VLAN tables: {} for dev: {}",
+                          pwRule, deviceId);
+                ops = install ? ops.add(pwRule) : ops.remove(pwRule);
+            }
+            // We push the filtering rules for the pw.
+            flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
+                @Override
+                public void onSuccess(FlowRuleOperations ops) {
+                    log.info("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);
+                }
+            }));
+
+            return;
+        }
+        // If it is not a pseudo wire flow we fall back
+        // to the OFDPA 2.0 pipeline.
+        super.processFilter(filteringObjective, install, applicationId);
+    }
+
+    /**
+     * Method to process the pw related filtering objectives.
+     *
+     * @param portCriterion the in port match
+     * @param innerVlanIdCriterion the inner vlan match
+     * @param outerVlanIdCriterion the outer vlan match
+     * @param tunnelId the tunnel id
+     * @param applicationId the application id
+     * @return a list of flow rules to install
+     */
+    private List<FlowRule> processPwFilter(PortCriterion portCriterion,
+                                             VlanIdCriterion innerVlanIdCriterion,
+                                             VlanIdCriterion outerVlanIdCriterion,
+                                             long tunnelId,
+                                             ApplicationId applicationId) {
+        // As first we create the flow rule for the vlan 1 table.
+        FlowRule vlan1FlowRule;
+        int mplsLogicalPort = ((int) portCriterion.port().toLong());
+        // We have to match on the inner vlan and outer vlan at the same time.
+        // Ofdpa supports this through the OVID meta-data type.
+        TrafficSelector.Builder vlan1Selector = DefaultTrafficSelector.builder()
+                .matchInPort(portCriterion.port())
+                .extension(new OfdpaMatchVlanVid(innerVlanIdCriterion.vlanId()), deviceId)
+                .extension(new Ofdpa3MatchOvid(outerVlanIdCriterion.vlanId()), deviceId);
+        // TODO understand for the future how to manage the vlan rewrite.
+        TrafficTreatment.Builder vlan1Treatment = DefaultTrafficTreatment.builder()
+                .pushVlan()
+                .setVlanId(outerVlanIdCriterion.vlanId())
+                .extension(new Ofdpa3SetMplsType(VPWS), deviceId)
+                .extension(new Ofdpa3SetMplsL2Port(mplsLogicalPort), deviceId)
+                .setTunnelId(tunnelId)
+                .transition(MPLS_L2_PORT_FLOW_TABLE);
+        vlan1FlowRule = DefaultFlowRule.builder()
+                .forDevice(deviceId)
+                .withSelector(vlan1Selector.build())
+                .withTreatment(vlan1Treatment.build())
+                .withPriority(DEFAULT_PRIORITY)
+                .fromApp(applicationId)
+                .makePermanent()
+                .forTable(VLAN_1_TABLE)
+                .build();
+        // Finally we create the flow rule for the vlan table.
+        FlowRule vlanFlowRule;
+        // We have to match on the outer vlan.
+        TrafficSelector.Builder vlanSelector = DefaultTrafficSelector.builder()
+                .matchInPort(portCriterion.port())
+                .extension(new OfdpaMatchVlanVid(outerVlanIdCriterion.vlanId()), deviceId);
+        // TODO understand for the future how to manage the vlan rewrite.
+        TrafficTreatment.Builder vlanTreatment = DefaultTrafficTreatment.builder()
+                .popVlan()
+                .extension(new Ofdpa3SetOvid(outerVlanIdCriterion.vlanId()), deviceId)
+                .transition(VLAN_1_TABLE);
+        vlanFlowRule = DefaultFlowRule.builder()
+                .forDevice(deviceId)
+                .withSelector(vlanSelector.build())
+                .withTreatment(vlanTreatment.build())
+                .withPriority(DEFAULT_PRIORITY)
+                .fromApp(applicationId)
+                .makePermanent()
+                .forTable(VLAN_TABLE)
+                .build();
+
+        return ImmutableList.of(vlan1FlowRule, vlanFlowRule);
+    }
+
+    @Override
     protected List<FlowRule> processVlanIdFilter(PortCriterion portCriterion,
                                                  VlanIdCriterion vidCriterion,
                                                  VlanId assignedVlan,
@@ -59,4 +269,104 @@
         }
         return processEthTypeSpecificInternal(fwd, true, MPLS_L3_TYPE_TABLE);
     }
+
+    @Override
+    protected Collection<FlowRule> processVersatile(ForwardingObjective fwd) {
+        // We use the tunnel id to identify pw related flows.
+        TunnelIdCriterion tunnelIdCriterion = (TunnelIdCriterion) fwd.selector()
+                .getCriterion(TUNNEL_ID);
+        if (tunnelIdCriterion != null) {
+            return processPwVersatile(fwd);
+        }
+        // If it is not a pseudo wire flow we fall back
+        // to the OFDPA 2.0 pipeline.
+        return super.processVersatile(fwd);
+    }
+
+    /**
+     * Helper method to process the pw forwarding objectives.
+     *
+     * @param forwardingObjective the fw objective to process
+     * @return a singleton list of flow rule
+     */
+    private Collection<FlowRule> processPwVersatile(ForwardingObjective forwardingObjective) {
+        // We retrieve the matching criteria for mpls l2 port.
+        TunnelIdCriterion tunnelIdCriterion = (TunnelIdCriterion) forwardingObjective.selector()
+                .getCriterion(TUNNEL_ID);
+        PortCriterion portCriterion = (PortCriterion) forwardingObjective.selector()
+                .getCriterion(IN_PORT);
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+        int mplsLogicalPort;
+        long tunnelId;
+        // Mpls tunnel ids according to the OFDPA manual have to be
+        // in the range [2^17-1, 2^16].
+        tunnelId = MPLS_TUNNEL_ID_BASE | tunnelIdCriterion.tunnelId();
+        if (tunnelId > MPLS_TUNNEL_ID_MAX) {
+            log.error("Pw Versatile Forwarding Objective must include tunnel id < {}",
+                      MPLS_TUNNEL_ID_MAX);
+            fail(forwardingObjective, ObjectiveError.BADPARAMS);
+            return Collections.emptySet();
+        }
+        // Port has not been null.
+        if (portCriterion == null) {
+            log.error("Pw Versatile Forwarding Objective must include port");
+            fail(forwardingObjective, ObjectiveError.BADPARAMS);
+            return Collections.emptySet();
+        }
+        // 0x0000XXXX is UNI interface.
+        if (portCriterion.port().toLong() > 0x0000FFFF) {
+            log.error("Pw Versatile Forwarding Objective invalid logical port {}",
+                      portCriterion.port().toLong());
+            fail(forwardingObjective, ObjectiveError.BADPARAMS);
+            return Collections.emptySet();
+        }
+        mplsLogicalPort = ((int) portCriterion.port().toLong());
+        if (forwardingObjective.nextId() == null) {
+            log.error("Pw Versatile Forwarding Objective must contain nextId ",
+                      forwardingObjective.nextId());
+            fail(forwardingObjective, ObjectiveError.BADPARAMS);
+            return Collections.emptySet();
+        }
+        // We don't expect a treatment.
+        if (forwardingObjective.treatment() != null &&
+                !forwardingObjective.treatment().equals(DefaultTrafficTreatment.emptyTreatment())) {
+            log.error("Pw Versatile Forwarding Objective cannot contain a treatment ",
+                      forwardingObjective.nextId());
+            fail(forwardingObjective, ObjectiveError.BADPARAMS);
+            return Collections.emptySet();
+        }
+        // We retrieve the l2 vpn group and point the mpls
+        // l2 port to this.
+        NextGroup next = getGroupForNextObjective(forwardingObjective.nextId());
+        if (next == null) {
+            log.warn("next-id:{} not found in dev:{}", forwardingObjective.nextId(), deviceId);
+            fail(forwardingObjective, ObjectiveError.GROUPMISSING);
+            return Collections.emptySet();
+        }
+        List<Deque<GroupKey>> gkeys = appKryo.deserialize(next.data());
+        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(), forwardingObjective.nextId(), deviceId);
+            fail(forwardingObjective, ObjectiveError.GROUPMISSING);
+            return Collections.emptySet();
+        }
+        // We prepare the flow rule for the mpls l2 port table.
+        selector.matchTunnelId(tunnelId);
+        selector.extension(new Ofdpa3MatchMplsL2Port(mplsLogicalPort), deviceId);
+        // This should not be necessary but without we receive an error
+        treatment.extension(new Ofdpa3SetQosIndex(0), deviceId);
+        treatment.transition(MPLS_L2_PORT_PCP_TRUST_FLOW_TABLE);
+        treatment.deferred().group(group.id());
+        FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
+                .fromApp(forwardingObjective.appId())
+                .withPriority(MPLS_L2_PORT_PRIORITY)
+                .forDevice(deviceId)
+                .withSelector(selector.build())
+                .withTreatment(treatment.build())
+                .makePermanent()
+                .forTable(MPLS_L2_PORT_FLOW_TABLE);
+        return Collections.singletonList(ruleBuilder.build());
+    }
 }
