diff --git a/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java b/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
index 2d4cc45..1423e06 100644
--- a/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
+++ b/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/src/main/java/org/onosproject/segmentrouting/pwaas/L2TunnelHandler.java b/src/main/java/org/onosproject/segmentrouting/pwaas/L2TunnelHandler.java
index 96fe6c9..5f0ed35 100644
--- a/src/main/java/org/onosproject/segmentrouting/pwaas/L2TunnelHandler.java
+++ b/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;
+        }
+    }
+
 }
