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 5f0ed35..8206180 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
@@ -19,6 +19,7 @@
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
 import org.apache.commons.lang3.RandomUtils;
+import org.onlab.packet.Ethernet;
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.MplsLabel;
 import org.onlab.packet.VlanId;
@@ -63,7 +64,10 @@
 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.Pipeline.TERMINATION;
 import static org.onosproject.segmentrouting.pwaas.L2TunnelHandler.Result.*;
+import static org.onosproject.segmentrouting.pwaas.L2TunnelHandler.Direction.FWD;
+import static org.onosproject.segmentrouting.pwaas.L2TunnelHandler.Direction.REV;
 
 /**
  * Handles pwaas related events.
@@ -71,20 +75,30 @@
 public class L2TunnelHandler {
 
     private static final Logger log = LoggerFactory.getLogger(L2TunnelHandler.class);
-
-    private static final String FWD = "f";
-    private static final String REV = "r";
-
-    private static final String NOT_MASTER = "Not master controller";
+    /**
+     * Error message for invalid paths.
+     */
     private static final String WRONG_TOPOLOGY = "Path in leaf-spine topology" +
             " should always be two hops: ";
 
     private final SegmentRoutingManager srManager;
-
-    private final ConsistentMap<String, NextObjective> l2InitiationNextObjStore;
-
     /**
-     * TODO a proper store is necessary to handle the policies and collisions.
+     * To store the next objectives related to the initiation.
+     */
+    private final ConsistentMap<String, NextObjective> l2InitiationNextObjStore;
+    /**
+     * To store the next objectives related to the termination.
+     */
+    private final ConsistentMap<String, NextObjective> l2TerminationNextObjStore;
+    /**
+     * TODO a proper store is necessary to handle the policies, collisions and recovery.
+     * We should have a proper store for the policies and the tunnels. For several reasons:
+     * 1) We should avoid the overlapping of different policies;
+     * 2) We should avoid the overlapping of different tunnels;
+     * 3) We should have a proper mechanism for the protection;
+     * The most important one is 3). At least for 3.0 EA0 was not possible
+     * to remove the bucket, so we need a mapping between policies and tunnel
+     * in order to proper update the fwd objective for the recovery of a fault.
      */
     private final KryoNamespace.Builder l2TunnelKryo;
 
@@ -104,6 +118,12 @@
                 .withName("onos-l2initiation-nextobj-store")
                 .withSerializer(Serializer.using(l2TunnelKryo.build()))
                 .build();
+
+        l2TerminationNextObjStore = srManager.storageService
+                .<String, NextObjective>consistentMapBuilder()
+                .withName("onos-l2termination-nextobj-store")
+                .withSerializer(Serializer.using(l2TunnelKryo.build()))
+                .build();
     }
 
     /**
@@ -122,6 +142,11 @@
         deploy(pwToAdd);
     }
 
+    /**
+     * To deploy a number of pseudo wires.
+     *
+     * @param pwToAdd the set of pseudo wires to add
+     */
     private void deploy(Set<DefaultL2TunnelDescription> pwToAdd) {
         Result result;
         long l2TunnelId;
@@ -129,7 +154,7 @@
             l2TunnelId = currentL2Tunnel.l2Tunnel().tunnelId();
             // The tunnel id cannot be 0.
             if (l2TunnelId == 0) {
-                log.warn("Tunnel id cannot be 0");
+                log.warn("Tunnel id id must be > 0");
                 continue;
             }
             // We do a sanity check of the pseudo wire.
@@ -138,7 +163,7 @@
                 continue;
             }
             // We establish the tunnel.
-            result = deployPseudoWire(
+            result = deployPseudoWireInit(
                     currentL2Tunnel.l2Tunnel(),
                     currentL2Tunnel.l2TunnelPolicy().cP1(),
                     currentL2Tunnel.l2TunnelPolicy().cP2(),
@@ -158,8 +183,18 @@
             if (result != SUCCESS) {
                 continue;
             }
+            // We terminate the tunnel
+            result = deployPseudoWireTerm(
+                    currentL2Tunnel.l2Tunnel(),
+                    currentL2Tunnel.l2TunnelPolicy().cP2(),
+                    currentL2Tunnel.l2TunnelPolicy().cP2OuterTag(),
+                    FWD
+            );
+            if (result != SUCCESS) {
+                continue;
+            }
             // We establish the reverse tunnel.
-            result = deployPseudoWire(
+            result = deployPseudoWireInit(
                     currentL2Tunnel.l2Tunnel(),
                     currentL2Tunnel.l2TunnelPolicy().cP2(),
                     currentL2Tunnel.l2TunnelPolicy().cP1(),
@@ -168,18 +203,27 @@
             if (result != SUCCESS) {
                 continue;
             }
-            deployPolicy(
+            result = deployPolicy(
                     l2TunnelId,
                     currentL2Tunnel.l2TunnelPolicy().cP2(),
                     currentL2Tunnel.l2TunnelPolicy().cP2InnerTag(),
                     currentL2Tunnel.l2TunnelPolicy().cP2OuterTag(),
                     result.nextId
             );
+            if (result != SUCCESS) {
+                continue;
+            }
+            deployPseudoWireTerm(
+                    currentL2Tunnel.l2Tunnel(),
+                    currentL2Tunnel.l2TunnelPolicy().cP1(),
+                    currentL2Tunnel.l2TunnelPolicy().cP1OuterTag(),
+                    REV
+            );
         }
     }
 
     /**
-     * Processes Pwaas Config updated event.
+     * Processes PWaaS Config updated event.
      *
      * @param event network config updated event
      */
@@ -209,12 +253,10 @@
                 .collect(Collectors.toSet());
         deploy(pwToAdd);
         // The pseudo wires to update.
-        updPws.forEach(tunnelId -> {
-            updatePw(
-                    prevConfig.getPwDescription(tunnelId),
-                    config.getPwDescription(tunnelId)
-            );
-        });
+        updPws.forEach(tunnelId -> updatePw(
+                prevConfig.getPwDescription(tunnelId),
+                config.getPwDescription(tunnelId))
+        );
     }
 
     /**
@@ -225,88 +267,91 @@
      */
     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<>();
+        CompletableFuture<ObjectiveError> fwdTermNextFuture = new CompletableFuture<>();
+        CompletableFuture<ObjectiveError> revTermNextFuture = new CompletableFuture<>();
+        CompletableFuture<ObjectiveError> fwdPwFuture = new CompletableFuture<>();
+        CompletableFuture<ObjectiveError> revPwFuture = new CompletableFuture<>();
 
-        result = verifyPseudoWire(newPw);
+
+        Result 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
+                fwdInitNextFuture,
+                FWD
         );
-        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
-                );
-            }
-        });
+        log.debug("Start deleting rev policy for {}", tunnelId);
+        deletePolicy(
+                tunnelId,
+                oldPw.l2TunnelPolicy().cP2(),
+                oldPw.l2TunnelPolicy().cP2InnerTag(),
+                oldPw.l2TunnelPolicy().cP2OuterTag(),
+                revInitNextFuture,
+                REV
+        );
         // 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,
+                log.debug("Fwd policy removed. Now remove fwd {} for {}", INITIATION, tunnelId);
+                tearDownPseudoWireInit(
+                        tunnelId,
                         oldPw.l2TunnelPolicy().cP1(),
-                        oldPw.l2TunnelPolicy().cP2(),
-                        revInitNextFuture
+                        fwdTermNextFuture,
+                        FWD
                 );
             }
         });
         revInitNextFuture.thenAcceptAsync(status -> {
            if (status == null) {
-               log.debug("Fwd tunnel removed. Now remove rev pw for {}", tunnelId);
-               tearDownPseudoWire(
-                       revKey,
-                       revNextObjective,
+               log.debug("Rev policy removed. Now remove rev {} for {}", INITIATION, tunnelId);
+               tearDownPseudoWireInit(
+                       tunnelId,
                        oldPw.l2TunnelPolicy().cP2(),
-                       oldPw.l2TunnelPolicy().cP1(),
-                       newPwFuture
+                       revTermNextFuture,
+                       REV
                );
 
            }
         });
+        fwdTermNextFuture.thenAcceptAsync(status -> {
+            if (status == null) {
+                log.debug("Fwd {} removed. Now remove fwd {} for {}", INITIATION, TERMINATION, tunnelId);
+                tearDownPseudoWireTerm(
+                        oldPw.l2Tunnel(),
+                        oldPw.l2TunnelPolicy().cP2(),
+                        fwdPwFuture,
+                        FWD
+                );
+            }
+        });
+        revTermNextFuture.thenAcceptAsync(status -> {
+            if (status == null) {
+                log.debug("Rev {} removed. Now remove rev {} for {}", INITIATION, TERMINATION, tunnelId);
+                tearDownPseudoWireTerm(
+                        oldPw.l2Tunnel(),
+                        oldPw.l2TunnelPolicy().cP1(),
+                        revPwFuture,
+                        REV
+                );
+            }
+        });
         // At the end we install the new pw.
-        newPwFuture.thenAcceptAsync(status -> {
+        fwdPwFuture.thenAcceptAsync(status -> {
             if (status == null) {
                 log.debug("Deploying new fwd pw for {}", tunnelId);
-                Result lamdaResult = deployPseudoWire(
+                Result lamdaResult = deployPseudoWireInit(
                         newPw.l2Tunnel(),
                         newPw.l2TunnelPolicy().cP1(),
                         newPw.l2TunnelPolicy().cP2(),
@@ -322,8 +367,22 @@
                         newPw.l2TunnelPolicy().cP1OuterTag(),
                         lamdaResult.nextId
                 );
+                if (lamdaResult != SUCCESS) {
+                    return;
+                }
+                deployPseudoWireTerm(
+                        newPw.l2Tunnel(),
+                        newPw.l2TunnelPolicy().cP2(),
+                        newPw.l2TunnelPolicy().cP2OuterTag(),
+                        FWD
+                );
+
+            }
+        });
+        revPwFuture.thenAcceptAsync(status -> {
+            if (status == null) {
                 log.debug("Deploying new rev pw for {}", tunnelId);
-                lamdaResult = deployPseudoWire(
+                Result lamdaResult = deployPseudoWireInit(
                         newPw.l2Tunnel(),
                         newPw.l2TunnelPolicy().cP2(),
                         newPw.l2TunnelPolicy().cP1(),
@@ -339,6 +398,15 @@
                         newPw.l2TunnelPolicy().cP2OuterTag(),
                         lamdaResult.nextId
                 );
+                if (lamdaResult != SUCCESS) {
+                    return;
+                }
+                deployPseudoWireTerm(
+                        newPw.l2Tunnel(),
+                        newPw.l2TunnelPolicy().cP1(),
+                        newPw.l2TunnelPolicy().cP1OuterTag(),
+                        REV
+                );
             }
         });
     }
@@ -366,11 +434,8 @@
      */
     private void tearDown(Set<DefaultL2TunnelDescription> pwToRemove) {
         Result result;
-        int nextId;
-        NextObjective nextObjective;
         long l2TunnelId;
-        // We remove all the pw in the configuration
-        // file.
+        // We remove all the pw in the configuration file.
         for (DefaultL2TunnelDescription currentL2Tunnel : pwToRemove) {
             l2TunnelId = currentL2Tunnel.l2Tunnel().tunnelId();
             if (l2TunnelId == 0) {
@@ -381,52 +446,48 @@
             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
+                    null,
+                    FWD
             );
             // Finally we will tear down the pseudo wire.
-            tearDownPseudoWire(
-                    key,
-                    nextObjective,
+            tearDownPseudoWireInit(
+                    l2TunnelId,
                     currentL2Tunnel.l2TunnelPolicy().cP1(),
+                    null,
+                    FWD
+            );
+            tearDownPseudoWireTerm(
+                    currentL2Tunnel.l2Tunnel(),
                     currentL2Tunnel.l2TunnelPolicy().cP2(),
-                    null
+                    null,
+                    FWD
             );
             // 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
+                    null,
+                    REV
             );
-            tearDownPseudoWire(
-                    key,
-                    nextObjective,
+            tearDownPseudoWireInit(
+                    l2TunnelId,
                     currentL2Tunnel.l2TunnelPolicy().cP2(),
+                    null,
+                    REV
+            );
+            tearDownPseudoWireTerm(
+                    currentL2Tunnel.l2Tunnel(),
                     currentL2Tunnel.l2TunnelPolicy().cP1(),
-                    null
+                    null,
+                    REV
             );
         }
 
@@ -444,7 +505,7 @@
         DefaultL2TunnelPolicy l2TunnelPolicy = l2TunnelDescription.l2TunnelPolicy();
         result = verifyTunnel(l2Tunnel);
         if (result != SUCCESS) {
-            log.warn("Tunnel {} did not pass the validation", l2Tunnel.tunnelId());
+            log.warn("Tunnel {}: did not pass the validation", l2Tunnel.tunnelId());
             return result;
         }
         result = verifyPolicy(
@@ -455,7 +516,7 @@
                 l2TunnelPolicy.cP2OuterTag()
         );
         if (result != SUCCESS) {
-            log.warn("Policy for tunnel {} did not pass the validation", l2Tunnel.tunnelId());
+            log.warn("Policy for tunnel {}: did not pass the validation", l2Tunnel.tunnelId());
             return result;
         }
 
@@ -463,8 +524,6 @@
     }
 
     /**
-     * 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.
@@ -474,27 +533,21 @@
      * @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.
+     * @return the result of the operation
      */
     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);
+            log.info("Abort creation of policy for tunnel {}: I am not the master", tunnelId);
             return SUCCESS;
         }
+        List<Objective> objectives = Lists.newArrayList();
         // We create the forwarding objective for supporting
         // the l2 tunnel.
-        fwdBuilder = createFwdObjective(
-                INITIATION,
+        ForwardingObjective.Builder fwdBuilder = createInitFwdObjective(
                 tunnelId,
                 ingress.port(),
                 nextId
@@ -508,7 +561,7 @@
         objectives.add(fwdBuilder.add(context));
         // We create the filtering objective to define the
         // permit traffic in the switch
-        filtBuilder = createFiltObjective(
+        FilteringObjective.Builder filtBuilder = createFiltObjective(
                 ingress.port(),
                 ingressInner,
                 ingressOuter
@@ -528,7 +581,7 @@
         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);
+                log.debug("Creating new FwdObj for initiation NextObj with id={} for tunnel {}", nextId, tunnelId);
             } else {
                 srManager.flowObjectiveService.filter(ingress.deviceId(), (FilteringObjective) objective);
                 log.debug("Creating new FiltObj for tunnel {}", tunnelId);
@@ -572,46 +625,36 @@
     }
 
     /**
-     * TODO Operation on the policies store.
-     *
      * Handles the tunnel establishment which consists in
-     * create the next objectives related to the initiation
-     * and termination.
+     * create the next objectives related to the initiation.
      *
      * @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
+     * @return the result of the operation
      */
-    private Result deployPseudoWire(DefaultL2Tunnel l2Tunnel,
-                                    ConnectPoint ingress,
-                                    ConnectPoint egress,
-                                    String direction) {
-        Link nextHop;
-        NextObjective.Builder nextObjectiveBuilder;
-        NextObjective nextObjective;
-        int nextId;
-        Result result;
+    private Result deployPseudoWireInit(DefaultL2Tunnel l2Tunnel,
+                                        ConnectPoint ingress,
+                                        ConnectPoint egress,
+                                        Direction direction) {
         if (!srManager.mastershipService.isLocalMaster(ingress.deviceId())) {
-            log.info("Abort initiation creation of L2 tunnel {}: {}",
-                     l2Tunnel.tunnelId(), NOT_MASTER);
+            log.info("Abort initiation of tunnel {}: I am not the master", l2Tunnel.tunnelId());
             return SUCCESS;
         }
         // We need at least a path between ingress and egress.
-        nextHop = getNextHop(ingress, egress);
+        Link 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(
+        // store. If not we store as it is in the store.
+        NextObjective.Builder nextObjectiveBuilder = createNextObjective(
                 INITIATION,
-                nextHop,
+                nextHop.src(),
+                nextHop.dst(),
                 l2Tunnel,
                 egress.deviceId()
         );
@@ -625,7 +668,7 @@
                 .matchTunnelId(l2Tunnel.tunnelId())
                 .build();
         nextObjectiveBuilder.withMeta(metadata);
-        nextId = srManager.flowObjectiveService.allocateNextId();
+        int nextId = srManager.flowObjectiveService.allocateNextId();
         if (nextId < 0) {
             log.warn("Not able to allocate a next id for initiation");
             return INTERNAL_ERROR;
@@ -640,18 +683,95 @@
                 (objective, error)
                         -> log.warn("Failed to populate Initiation l2 tunnel rule for {}: {}",
                                     l2Tunnel.tunnelId(), error));
-        nextObjective = nextObjectiveBuilder.add(context);
+        NextObjective 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 result = SUCCESS;
         result.nextId = nextObjective.id();
         return result;
     }
 
     /**
+     * Handles the tunnel termination, which consists in the creation
+     * of a forwarding objective and a next objective.
+     *
+     * @param l2Tunnel the tunnel to terminate
+     * @param egress the egress point
+     * @param egressVlan the expected vlan at egress
+     * @param direction the direction
+     * @return the result of the operation
+     */
+    private Result deployPseudoWireTerm(DefaultL2Tunnel l2Tunnel,
+                                        ConnectPoint egress,
+                                        VlanId egressVlan,
+                                        Direction direction) {
+        // We create the group relative to the termination.
+        // It's fine to abort the termination if we are
+        // not the master.
+        if (!srManager.mastershipService.isLocalMaster(egress.deviceId())) {
+            log.info("Abort termination of tunnel {}: I am not the master", l2Tunnel.tunnelId());
+            return SUCCESS;
+        }
+        NextObjective.Builder nextObjectiveBuilder = createNextObjective(
+                TERMINATION,
+                egress,
+                null,
+                null,
+                egress.deviceId()
+        );
+        if (nextObjectiveBuilder == null) {
+            return INTERNAL_ERROR;
+        }
+        TrafficSelector metadata = DefaultTrafficSelector
+                .builder()
+                .matchVlanId(egressVlan)
+                .build();
+        nextObjectiveBuilder.withMeta(metadata);
+        int 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);
+        l2TerminationNextObjStore.put(key, nextObjectiveBuilder.add());
+        ObjectiveContext context = new DefaultObjectiveContext(
+                (objective)
+                        -> log.debug("Termination l2 tunnel rule for {} populated",
+                                     l2Tunnel.tunnelId()),
+                (objective, error)
+                        -> log.warn("Failed to populate termination l2 tunnel rule for {}: {}",
+                                    l2Tunnel.tunnelId(), error));
+        NextObjective nextObjective = nextObjectiveBuilder.add(context);
+        srManager.flowObjectiveService.next(egress.deviceId(), nextObjective);
+        log.debug("Termination next objective for {} not found. Creating new NextObj with id={}",
+                  l2Tunnel.tunnelId(),
+                  nextObjective.id()
+        );
+        // We create the flow relative to the termination.
+        ForwardingObjective.Builder fwdBuilder = createTermFwdObjective(
+                l2Tunnel.pwLabel(),
+                l2Tunnel.tunnelId(),
+                egress.port(),
+                nextObjective.id()
+        );
+        context = new DefaultObjectiveContext(
+                (objective)
+                        -> log.debug("FwdObj for tunnel termination {} populated",
+                                     l2Tunnel.tunnelId()),
+                (objective, error)
+                        -> log.warn("Failed to populate fwdrObj for tunnel termination {}",
+                                    l2Tunnel.tunnelId(), error));
+        srManager.flowObjectiveService.forward(egress.deviceId(), fwdBuilder.add(context));
+        log.debug("Creating new FwdObj for termination NextObj with id={} for tunnel {}", nextId, l2Tunnel.tunnelId());
+        return SUCCESS;
+
+    }
+
+    /**
      * Helper method to verify if the tunnel is whether or not
      * supported.
      *
@@ -675,7 +795,7 @@
     }
 
     /**
-     * Create the filtering objective according to a given policy.
+     * Creates the filtering objective according to a given policy.
      *
      * @param inPort the in port
      * @param innerTag the inner vlan tag
@@ -695,34 +815,69 @@
     }
 
     /**
-     * Create the forwarding objective according to a given pipeline.
+     * Creates the forwarding objective for the termination.
      *
-     * @param pipeline the pipeline
+     * @param pwLabel the pseudo wire label
      * @param tunnelId the tunnel id
+     * @param egressPort the egress port
      * @param nextId the next step
-     * @return the forwarding objective to support the pipeline.
+     * @return the forwarding objective to support the termination
      */
-    private ForwardingObjective.Builder createFwdObjective(Pipeline pipeline,
-                                                           long tunnelId,
-                                                           PortNumber inPort,
-                                                           int nextId) {
-        ForwardingObjective.Builder fwdBuilder = null;
+    private ForwardingObjective.Builder createTermFwdObjective(MplsLabel pwLabel,
+                                                               long tunnelId,
+                                                               PortNumber egressPort,
+                                                               int nextId) {
         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;
+        TrafficTreatment.Builder trafficTreatment = DefaultTrafficTreatment
+                .builder();
+        // The flow has to match on the pw label and bos
+        trafficSelector.matchEthType(Ethernet.MPLS_UNICAST);
+        trafficSelector.matchMplsLabel(pwLabel);
+        trafficSelector.matchMplsBos(true);
+        // The flow has to decrement ttl, restore ttl in
+        // pop mpls, set tunnel id and port.
+        trafficTreatment.decMplsTtl();
+        trafficTreatment.copyTtlIn();
+        trafficTreatment.popMpls();
+        trafficTreatment.setTunnelId(tunnelId);
+        trafficTreatment.setOutput(egressPort);
+
+        return DefaultForwardingObjective.builder()
+                .fromApp(srManager.appId)
+                .makePermanent()
+                .nextStep(nextId)
+                .withPriority(SegmentRoutingService.DEFAULT_PRIORITY)
+                .withSelector(trafficSelector.build())
+                .withTreatment(trafficTreatment.build())
+                .withFlag(VERSATILE);
+    }
+
+    /**
+     * Creates the forwarding objective for the initiation.
+     *
+     * @param tunnelId the tunnel id
+     * @param inPort the input port
+     * @param nextId the next step
+     * @return the forwarding objective to support the initiation.
+     */
+    private ForwardingObjective.Builder createInitFwdObjective(long tunnelId,
+                                                               PortNumber inPort,
+                                                               int nextId) {
+        TrafficSelector.Builder trafficSelector = DefaultTrafficSelector
+                .builder();
+        // The flow has to match on the mpls logical
+        // port and the tunnel id.
+        trafficSelector.matchTunnelId(tunnelId);
+        trafficSelector.matchInPort(inPort);
+
+        return DefaultForwardingObjective.builder()
+                .fromApp(srManager.appId)
+                .makePermanent()
+                .nextStep(nextId)
+                .withPriority(SegmentRoutingService.DEFAULT_PRIORITY)
+                .withSelector(trafficSelector.build())
+                .withFlag(VERSATILE);
 
     }
 
@@ -733,13 +888,15 @@
      * the same next objective for different tunnels.
      *
      * @param pipeline the pipeline to support
-     * @param nextHop the next hop towards the destination
+     * @param srcCp the source port
+     * @param dstCp the destination port
      * @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,
+                                                      ConnectPoint srcCp,
+                                                      ConnectPoint dstCp,
                                                       DefaultL2Tunnel l2Tunnel,
                                                       DeviceId egressId) {
         NextObjective.Builder nextObjBuilder;
@@ -786,7 +943,7 @@
             try {
                 ingressMac = srManager
                         .deviceConfiguration
-                        .getDeviceMac(nextHop.src().deviceId());
+                        .getDeviceMac(srcCp.deviceId());
             } catch (DeviceConfigNotFoundException e) {
                 log.warn("Was not able to find the ingress mac");
                 return null;
@@ -796,20 +953,21 @@
             try {
                 neighborMac = srManager
                         .deviceConfiguration
-                        .getDeviceMac(nextHop.dst().deviceId());
+                        .getDeviceMac(dstCp.deviceId());
             } catch (DeviceConfigNotFoundException e) {
                 log.warn("Was not able to find the neighbor mac");
                 return null;
             }
             treatmentBuilder.setEthDst(neighborMac);
         } else {
+            // We create the next objective which
+            // will be a simple l2 group.
             nextObjBuilder = DefaultNextObjective
                     .builder()
                     .withType(NextObjective.Type.SIMPLE)
                     .fromApp(srManager.appId);
-
         }
-        treatmentBuilder.setOutput(nextHop.src().port());
+        treatmentBuilder.setOutput(srcCp.port());
         nextObjBuilder.addTreatment(treatmentBuilder.build());
         return nextObjBuilder;
     }
@@ -841,32 +999,41 @@
     }
 
     /**
-     * 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
+     * @param future to perform the async operation
+     * @param direction the direction: forward or reverse
      */
     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();
+                              CompletableFuture<ObjectiveError> future,
+                              Direction direction) {
         if (!srManager.mastershipService.isLocalMaster(ingress.deviceId())) {
-            log.info("Abort delete of policy for L2 tunnel {}: {}", tunnelId, NOT_MASTER);
+            log.info("Abort delete of policy for tunnel {}: I am not the master", tunnelId);
+            if (future != null) {
+                future.complete(null);
+            }
             return;
         }
+        String key = generateKey(tunnelId, direction);
+        if (!l2InitiationNextObjStore.containsKey(key)) {
+            log.warn("Abort delete of policy for tunnel {}: next does not exist in the store", tunnelId);
+            if (future != null) {
+                future.complete(null);
+            }
+            return;
+        }
+        NextObjective nextObjective = l2InitiationNextObjStore.get(key).value();
+        int nextId = nextObjective.id();
+        List<Objective> objectives = Lists.newArrayList();
         // We create the forwarding objective.
-        fwdBuilder = createFwdObjective(
-                INITIATION,
+        ForwardingObjective.Builder fwdBuilder = createInitFwdObjective(
                 tunnelId,
                 ingress.port(),
                 nextId
@@ -874,24 +1041,24 @@
         ObjectiveContext context = new ObjectiveContext() {
             @Override
             public void onSuccess(Objective objective) {
-                log.debug("Previous FwdObj for policy {} removed", tunnelId);
-                if (fwdFuture != null) {
-                    fwdFuture.complete(null);
+                log.debug("Previous fwdObj for policy {} removed", tunnelId);
+                if (future != null) {
+                    future.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);
+                log.warn("Failed to remove previous fwdObj for policy {}: {}", tunnelId, error);
+                if (future != null) {
+                    future.complete(error);
                 }
             }
         };
         objectives.add(fwdBuilder.remove(context));
         // We create the filtering objective to define the
         // permit traffic in the switch
-        filtBuilder = createFiltObjective(
+        FilteringObjective.Builder filtBuilder = createFiltObjective(
                 ingress.port(),
                 ingressInner,
                 ingressOuter
@@ -916,55 +1083,130 @@
     }
 
     /**
-     * TODO Operation on the store.
-     * Deletes a given pseudo wire using the parameter supplied.
+     * Deletes the pseudo wire initiation.
      *
-     * @param key the key of the store
-     * @param nextObjective the next objective representing the pw
+     * @param l2TunnelId the tunnel id
      * @param ingress the ingress connect point
-     * @param egress the egress connect point
+     * @param future to perform an async operation
+     * @param direction the direction: reverse of forward
      */
-    private void tearDownPseudoWire(String key,
-                                    NextObjective nextObjective,
-                                    ConnectPoint ingress,
-                                    ConnectPoint egress,
-                                    CompletableFuture<ObjectiveError> nextFutureForInit) {
+    private void tearDownPseudoWireInit(long l2TunnelId,
+                                        ConnectPoint ingress,
+                                        CompletableFuture<ObjectiveError> future,
+                                        Direction direction) {
+        String key = generateKey(l2TunnelId, direction);
         if (!srManager.mastershipService.isLocalMaster(ingress.deviceId())) {
-            log.info("Abort delete of {} for {}: {}", INITIATION, key, NOT_MASTER);
+            log.info("Abort delete of {} for {}: I am not the master", INITIATION, key);
+            if (future != null) {
+                future.complete(null);
+            }
             return;
         }
+        if (!l2InitiationNextObjStore.containsKey(key)) {
+            log.info("Abort delete of {} for {}: next does not exist in the store", INITIATION, key);
+            if (future != null) {
+                future.complete(null);
+            }
+            return;
+        }
+        NextObjective nextObjective = l2InitiationNextObjStore.get(key).value();
         ObjectiveContext context = new ObjectiveContext() {
             @Override
             public void onSuccess(Objective objective) {
-                log.debug("Previous {} NextObj for {} removed", INITIATION, key);
-                if (nextFutureForInit != null) {
-                    nextFutureForInit.complete(null);
+                log.debug("Previous {} next for {} removed", INITIATION, key);
+                if (future != null) {
+                    future.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);
+                log.warn("Failed to remove previous {} next for {}: {}", INITIATION, key, error);
+                if (future != null) {
+                    future.complete(error);
                 }
             }
         };
-        srManager.flowObjectiveService.next(
-                ingress.deviceId(),
-                (NextObjective) nextObjective.copy().remove(context)
-        );
+        srManager.flowObjectiveService
+                .next(ingress.deviceId(), (NextObjective) nextObjective.copy().remove(context));
         l2InitiationNextObjStore.remove(key);
     }
 
     /**
+     * Deletes the pseudo wire termination.
+     *
+     * @param l2Tunnel the tunnel
+     * @param egress the egress connect point
+     * @param future the async task
+     * @param direction the direction of the tunnel
+     */
+    private void tearDownPseudoWireTerm(DefaultL2Tunnel l2Tunnel,
+                                        ConnectPoint egress,
+                                        CompletableFuture<ObjectiveError> future,
+                                        Direction direction) {
+        /*
+         * We verify the mastership for the termination.
+         */
+        String key = generateKey(l2Tunnel.tunnelId(), direction);
+        if (!srManager.mastershipService.isLocalMaster(egress.deviceId())) {
+            log.info("Abort delete of {} for {}: I am not the master", TERMINATION, key);
+            if (future != null) {
+                future.complete(null);
+            }
+            return;
+        }
+        if (!l2TerminationNextObjStore.containsKey(key)) {
+            log.info("Abort delete of {} for {}: next does not exist in the store", TERMINATION, key);
+            if (future != null) {
+                future.complete(null);
+            }
+            return;
+        }
+        NextObjective nextObjective = l2TerminationNextObjStore.get(key).value();
+        ForwardingObjective.Builder fwdBuilder = createTermFwdObjective(
+                l2Tunnel.pwLabel(),
+                l2Tunnel.tunnelId(),
+                egress.port(),
+                nextObjective.id()
+        );
+        ObjectiveContext context = new DefaultObjectiveContext(
+                (objective)
+                        -> log.debug("FwdObj for {} {} removed", TERMINATION, l2Tunnel.tunnelId()),
+                (objective, error)
+                        -> log.warn("Failed to remove fwdObj for {} {}", TERMINATION, l2Tunnel.tunnelId(),
+                                    error));
+        srManager.flowObjectiveService.forward(egress.deviceId(), fwdBuilder.remove(context));
+
+        context = new ObjectiveContext() {
+            @Override
+            public void onSuccess(Objective objective) {
+                log.debug("Previous {} next for {} removed", TERMINATION, key);
+                if (future != null) {
+                    future.complete(null);
+                }
+            }
+
+            @Override
+            public void onError(Objective objective, ObjectiveError error) {
+                log.warn("Failed to remove previous {} next for {}: {}", TERMINATION, key, error);
+                if (future != null) {
+                    future.complete(error);
+                }
+            }
+        };
+        srManager.flowObjectiveService
+                .next(egress.deviceId(), (NextObjective) nextObjective.copy().remove(context));
+        l2TerminationNextObjStore.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) {
+    private String generateKey(long tunnelId, Direction direction) {
         return String.format("%s-%s", tunnelId, direction);
     }
 
@@ -979,7 +1221,7 @@
         /**
          * The termination pipeline.
          */
-        TERMINATION;
+        TERMINATION
     }
 
     /**
@@ -1012,7 +1254,7 @@
         private final String description;
         private int nextId;
 
-        private Result(int code, String description) {
+        Result(int code, String description) {
             this.code = code;
             this.description = description;
         }
@@ -1021,14 +1263,24 @@
             return description;
         }
 
-        public int getCode() {
-            return code;
-        }
-
         @Override
         public String toString() {
             return code + ": " + description;
         }
     }
 
+    /**
+     * Enum helper for handling the direction of the pw.
+     */
+    public enum Direction {
+        /**
+         * The forward direction of the pseudo wire.
+         */
+        FWD,
+        /**
+         * The reverse direction of the pseudo wire.
+         */
+        REV;
+    }
+
 }
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 e32f5d5..9da1e27 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
@@ -129,6 +129,11 @@
     protected static final int MPLS_TUNNEL_ID_BASE = 0x10000;
     protected static final int MPLS_TUNNEL_ID_MAX = 0x1FFFF;
 
+    protected static final int MPLS_UNI_PORT_MAX = 0x0000FFFF;
+
+    protected static final int MPLS_NNI_PORT_BASE = 0x00020000;
+    protected static final int MPLS_NNI_PORT_MAX = 0x0002FFFF;
+
     private final Logger log = getLogger(getClass());
     protected ServiceDirectory serviceDirectory;
     protected FlowRuleService flowRuleService;
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 38fe384..db01906 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
@@ -21,6 +21,8 @@
 import org.onosproject.core.ApplicationId;
 import org.onosproject.driver.extensions.Ofdpa3MatchMplsL2Port;
 import org.onosproject.driver.extensions.Ofdpa3MatchOvid;
+import org.onosproject.driver.extensions.Ofdpa3PopCw;
+import org.onosproject.driver.extensions.Ofdpa3PopL2Header;
 import org.onosproject.driver.extensions.Ofdpa3SetMplsL2Port;
 import org.onosproject.driver.extensions.Ofdpa3SetMplsType;
 import org.onosproject.driver.extensions.Ofdpa3SetOvid;
@@ -40,8 +42,11 @@
 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.Instruction;
+import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
 import org.onosproject.net.flow.instructions.L2ModificationInstruction;
 import org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType;
+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;
@@ -146,7 +151,7 @@
                 return;
             }
             // 0x0000XXXX is UNI interface.
-            if (portCriterion.port().toLong() > 0x0000FFFF) {
+            if (portCriterion.port().toLong() > MPLS_UNI_PORT_MAX) {
                 log.error("Filering Objective invalid logical port {}",
                           portCriterion.port().toLong());
                 fail(filteringObjective, ObjectiveError.BADPARAMS);
@@ -273,23 +278,104 @@
     @Override
     protected Collection<FlowRule> processVersatile(ForwardingObjective fwd) {
         // We use the tunnel id to identify pw related flows.
+        // Looking for the fwd objective of the initiation.
         TunnelIdCriterion tunnelIdCriterion = (TunnelIdCriterion) fwd.selector()
                 .getCriterion(TUNNEL_ID);
         if (tunnelIdCriterion != null) {
-            return processPwVersatile(fwd);
+            return processInitPwVersatile(fwd);
+        }
+        // Looking for the fwd objective of the termination.
+        ModTunnelIdInstruction modTunnelIdInstruction = getModTunnelIdInstruction(fwd.treatment());
+        OutputInstruction outputInstruction = getOutputInstruction(fwd.treatment());
+        if (modTunnelIdInstruction != null && outputInstruction != null) {
+            return processTermPwVersatile(fwd, modTunnelIdInstruction, outputInstruction);
         }
         // If it is not a pseudo wire flow we fall back
         // to the OFDPA 2.0 pipeline.
         return super.processVersatile(fwd);
     }
 
+    private Collection<FlowRule> processTermPwVersatile(ForwardingObjective forwardingObjective,
+                                                        ModTunnelIdInstruction modTunnelIdInstruction,
+                                                        OutputInstruction outputInstruction) {
+        TrafficTreatment.Builder flowTreatment;
+        TrafficSelector.Builder flowSelector;
+        // We divide the mpls actions from the tunnel actions. We need
+        // this to order the actions in the final treatment.
+        TrafficTreatment.Builder mplsTreatment = DefaultTrafficTreatment.builder();
+        createMplsTreatment(forwardingObjective.treatment(), mplsTreatment);
+        // The match of the forwarding objective is ready to go.
+        flowSelector = DefaultTrafficSelector.builder(forwardingObjective.selector());
+        // We verify the tunnel id and mpls port are correct.
+        long tunnelId = MPLS_TUNNEL_ID_BASE | modTunnelIdInstruction.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();
+        }
+        // 0x0002XXXX is NNI interface.
+        int mplsLogicalPort = ((int) outputInstruction.port().toLong()) | MPLS_NNI_PORT_BASE;
+        if (mplsLogicalPort > MPLS_NNI_PORT_MAX) {
+            log.error("Pw Versatile Forwarding Objective invalid logical port {}",
+                      mplsLogicalPort);
+            fail(forwardingObjective, ObjectiveError.BADPARAMS);
+            return Collections.emptySet();
+        }
+        // Next id cannot be null.
+        if (forwardingObjective.nextId() == null) {
+            log.error("Pw Versatile Forwarding Objective must contain nextId ",
+                      forwardingObjective.nextId());
+            fail(forwardingObjective, ObjectiveError.BADPARAMS);
+            return Collections.emptySet();
+        }
+        // We retrieve the l2 interface group and point the mpls
+        // flow 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 treatment for the mpls flow table.
+        // The order of the actions has to be strictly this
+        // according to the OFDPA 2.0 specification.
+        flowTreatment = DefaultTrafficTreatment.builder(mplsTreatment.build());
+        flowTreatment.extension(new Ofdpa3PopCw(), deviceId);
+        flowTreatment.popVlan();
+        flowTreatment.extension(new Ofdpa3PopL2Header(), deviceId);
+        flowTreatment.setTunnelId(tunnelId);
+        flowTreatment.extension(new Ofdpa3SetMplsL2Port(mplsLogicalPort), deviceId);
+        flowTreatment.extension(new Ofdpa3SetMplsType(VPWS), deviceId);
+        flowTreatment.transition(MPLS_TYPE_TABLE);
+        flowTreatment.deferred().group(group.id());
+        // We prepare the flow rule for the mpls table.
+        FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
+                .fromApp(forwardingObjective.appId())
+                .withPriority(forwardingObjective.priority())
+                .forDevice(deviceId)
+                .withSelector(flowSelector.build())
+                .withTreatment(flowTreatment.build())
+                .makePermanent()
+                .forTable(MPLS_TABLE_1);
+        return Collections.singletonList(ruleBuilder.build());
+    }
+
     /**
      * 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) {
+    private Collection<FlowRule> processInitPwVersatile(ForwardingObjective forwardingObjective) {
         // We retrieve the matching criteria for mpls l2 port.
         TunnelIdCriterion tunnelIdCriterion = (TunnelIdCriterion) forwardingObjective.selector()
                 .getCriterion(TUNNEL_ID);
@@ -315,7 +401,7 @@
             return Collections.emptySet();
         }
         // 0x0000XXXX is UNI interface.
-        if (portCriterion.port().toLong() > 0x0000FFFF) {
+        if (portCriterion.port().toLong() > MPLS_UNI_PORT_MAX) {
             log.error("Pw Versatile Forwarding Objective invalid logical port {}",
                       portCriterion.port().toLong());
             fail(forwardingObjective, ObjectiveError.BADPARAMS);
@@ -369,4 +455,94 @@
                 .forTable(MPLS_L2_PORT_FLOW_TABLE);
         return Collections.singletonList(ruleBuilder.build());
     }
+
+    /**
+     * Utility function to get the mod tunnel id instruction
+     * if present.
+     *
+     * @param treatment the treatment to analyze
+     * @return the mod tunnel id instruction if present,
+     * otherwise null
+     */
+    private ModTunnelIdInstruction getModTunnelIdInstruction(TrafficTreatment treatment) {
+        L2ModificationInstruction l2ModificationInstruction;
+        for (Instruction instruction : treatment.allInstructions()) {
+            if (instruction.type() == L2MODIFICATION) {
+                l2ModificationInstruction = (L2ModificationInstruction) instruction;
+                if (l2ModificationInstruction.subtype() == L2SubType.TUNNEL_ID) {
+                    return (ModTunnelIdInstruction) l2ModificationInstruction;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Utility function to get the output instruction
+     * if present.
+     *
+     * @param treatment the treatment to analyze
+     * @return the output instruction if present,
+     * otherwise null
+     */
+    private OutputInstruction getOutputInstruction(TrafficTreatment treatment) {
+        for (Instruction instruction : treatment.allInstructions()) {
+            if (instruction.type() == Instruction.Type.OUTPUT) {
+                return (OutputInstruction) instruction;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Helper method for dividing the tunnel instructions from the mpls
+     * instructions.
+     *
+     * @param treatment the treatment to analyze
+     * @param mplsTreatment the mpls treatment builder
+     */
+    private void createMplsTreatment(TrafficTreatment treatment,
+                                     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 mpls
+                    // treatment.
+                    case TUNNEL_ID:
+                        break;
+                    case DEC_MPLS_TTL:
+                    case MPLS_POP:
+                        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) {
+                break;
+            } else if (ins.type() == Instruction.Type.L3MODIFICATION) {
+                // We support partially the l3 instructions.
+                L3ModificationInstruction l3ins = (L3ModificationInstruction) ins;
+                switch (l3ins.subtype()) {
+                    case TTL_IN:
+                        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);
+            }
+        }
+    }
 }
