diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/PseudowireAddCommand.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/PseudowireAddCommand.java
index 277a1c3..d7d22b4 100644
--- a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/PseudowireAddCommand.java
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/PseudowireAddCommand.java
@@ -100,8 +100,9 @@
 
         try {
             tun = new DefaultL2Tunnel(parseMode(mode), parseVlan(sDTag), parsePwId(pwId), parsePWLabel(pwLabel));
-        } catch (Exception e) {
-            print("Exception while parsing L2Tunnel : {}", e);
+        } catch (IllegalArgumentException e) {
+            log.error("Exception while parsing L2Tunnel : \n\t %s", e.getMessage());
+            print("Exception while parsing L2Tunnel : \n\t %s", e.getMessage());
             return;
         }
 
@@ -111,13 +112,15 @@
                                                parseVlan(cP1OuterVlan), ConnectPoint.deviceConnectPoint(cP2),
                                                parseVlan(cP2InnerVlan), parseVlan(cP2OuterVlan));
 
-        } catch (Exception e) {
-            print("Exception while parsing L2TunnelPolicy : {}", e);
+        } catch (IllegalArgumentException e) {
+            log.error("Exception while parsing L2TunnelPolicy : \n\t %s", e.getMessage());
+            print("Exception while parsing L2TunnelPolicy : \n\t %s", e.getMessage());
             return;
         }
 
         L2TunnelDescription pw = new DefaultL2TunnelDescription(tun, policy);
         L2TunnelHandler.Result res = srService.addPseudowire(pw);
+        log.info("Deploying pseudowire {} via the command line.", pw);
         switch (res) {
             case WRONG_PARAMETERS:
                 print("Pseudowire could not be added , error in the parameters : \n\t%s",
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/PseudowireRemoveCommand.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/PseudowireRemoveCommand.java
index 362ebbb..d0f217d 100644
--- a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/PseudowireRemoveCommand.java
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/PseudowireRemoveCommand.java
@@ -49,11 +49,13 @@
         int pwIntId;
         try {
             pwIntId = parsePwId(pwId);
-        } catch (Exception e) {
-            print("Exception while parsing pseudowire id : {}", e);
+        } catch (IllegalArgumentException e) {
+            log.error("Exception while parsing pseudowire id : \n\t %s", e.getMessage());
+            print("Exception while parsing pseudowire id : \n\t %s", e.getMessage());
             return;
         }
 
+        log.info("Removing pseudowire {} from the command line.", pwIntId);
         L2TunnelHandler.Result res = mngr.removePseudowire(pwIntId);
         switch (res) {
             case WRONG_PARAMETERS:
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2TunnelHandler.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2TunnelHandler.java
index eb18381..a8b94e0 100644
--- a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2TunnelHandler.java
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2TunnelHandler.java
@@ -52,8 +52,10 @@
 import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
 import org.onosproject.store.serializers.KryoNamespaces;
 import org.onosproject.store.service.ConsistentMap;
+import org.onosproject.store.service.DistributedLock;
 import org.onosproject.store.service.DistributedSet;
 import org.onosproject.store.service.Serializer;
+import org.onosproject.store.service.StorageException;
 import org.onosproject.store.service.Versioned;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -74,10 +76,11 @@
 import static org.onosproject.segmentrouting.pwaas.PwaasUtil.*;
 
 /**
- * Handles pwaas related events.
+ * Handler for pseudowire management.
  */
 public class DefaultL2TunnelHandler implements L2TunnelHandler {
 
+    private static final String LOCK_NAME = "l2-tunnel-handler-lock";
     private static final Logger log = LoggerFactory.getLogger(DefaultL2TunnelHandler.class);
 
     private final SegmentRoutingManager srManager;
@@ -118,6 +121,13 @@
     private final DistributedSet<VlanId> vlanStore;
 
     /**
+     * Lock used when creating or removing pseudowires.
+     */
+    private final DistributedLock pwLock;
+
+    private static final long LOCK_TIMEOUT = 2000;
+
+    /**
      * Used for determining transport vlans for leaf-spine.
      */
     private short transportVlanUpper = 4093, transportVlanLower = 3500;
@@ -188,6 +198,11 @@
                                 .build()))
                 .build()
                 .asDistributedSet();
+
+        pwLock = srManager.storageService.lockBuilder()
+                .withName(LOCK_NAME)
+                .build()
+                .asLock(LOCK_TIMEOUT);
     }
 
     /**
@@ -281,10 +296,7 @@
     private Result manageIntermediateFiltering(L2TunnelDescription pw, boolean leafSpinePw) {
 
         // only leaf-spine-spine should need intermediate rules for now
-        if (!leafSpinePw) {
-            return Result.SUCCESS;
-        }
-        if (pw.l2Tunnel().pathUsed().size() != 2) {
+        if (!leafSpinePw || (pw.l2Tunnel().pathUsed().size() != 2)) {
             return Result.SUCCESS;
         }
 
@@ -292,7 +304,7 @@
         DeviceId intermediateSpineId = pw.l2Tunnel().pathUsed().get(0).dst().deviceId();
         L2Tunnel l2Tunnel = pw.l2Tunnel();
 
-        log.info("Installing intermediate filtering rules for spine {} , for pseudowire {}",
+        log.debug("Installing intermediate filtering rules for spine {} , for pseudowire {}",
                  intermediateSpineId, pw.l2Tunnel().tunnelId());
 
         MacAddress dstMac;
@@ -394,7 +406,7 @@
 
         if (!spinePw) {
 
-            log.info("Untagged transport with internal vlan {} for pseudowire!", UNTAGGED_TRANSPORT_VLAN);
+            log.debug("Untagged transport with internal vlan {} for pseudowire!", UNTAGGED_TRANSPORT_VLAN);
             return UNTAGGED_TRANSPORT_VLAN;
         } else {
             for (short i = transportVlanUpper; i > transportVlanLower; i--) {
@@ -403,12 +415,12 @@
                 if (!vlanStore.contains(vlanToUse)) {
 
                     vlanStore.add(vlanToUse);
-                    log.info("Transport vlan {} for pseudowire!", vlanToUse);
+                    log.debug("Transport vlan {} for pseudowire!", vlanToUse);
                     return vlanToUse;
                 }
             }
 
-            log.info("No available transport vlan found, pseudowire traffic will be carried untagged " +
+            log.warn("No available transport vlan found, pseudowire traffic will be carried untagged " +
                              "with internal vlan {}!", UNTAGGED_TRANSPORT_VLAN);
             return UNTAGGED_TRANSPORT_VLAN;
         }
@@ -455,6 +467,7 @@
      */
     private boolean isValidPath(List<Link> path, boolean leafSpinePw) {
 
+        log.debug("Checking path validity for pseudowire.");
         List<DeviceId> devices = getDevicesOnPath(path);
         if (devices.size() < 2) {
             log.error("Path size for pseudowire should be greater than 1!");
@@ -528,196 +541,202 @@
      */
     public Result deployPseudowire(L2TunnelDescription pw) {
 
-        Result result;
-        long l2TunnelId;
-
-        log.debug("Pseudowire with {} deployment started, check log for any errors in this process!",
-                  pw.l2Tunnel().tunnelId());
-
-        l2TunnelId = pw.l2Tunnel().tunnelId();
-        // The tunnel id cannot be 0.
-        if (l2TunnelId == 0) {
-            log.warn("Tunnel id id must be > 0");
-            return Result.WRONG_PARAMETERS
-                    .appendError("Tunnel id id must be > 0");
-        }
-
-        result = verifyGlobalValidity(pw);
-        if (result != SUCCESS) {
-            log.error("Global validity for pseudowire {} is wrong!", l2TunnelId);
-            return result;
-        }
-
-        // leafSpinePw determines if this is a leaf-leaf
-        // or leaf-spine pseudowire
-        boolean leafSpinePw;
-        ConnectPoint cp1 = pw.l2TunnelPolicy().cP1();
-        ConnectPoint cp2 = pw.l2TunnelPolicy().cP2();
         try {
-            // differentiate between leaf-leaf pseudowires and leaf-spine
-            if (!srManager.deviceConfiguration().isEdgeDevice(cp1.deviceId()) &&
-                    !srManager.deviceConfiguration().isEdgeDevice(cp2.deviceId())) {
-                log.error("Can not deploy pseudowire from spine to spine!");
+            // take the lock
+            pwLock.lock();
+            Result result;
+            long l2TunnelId;
+            log.debug("Pseudowire with {} deployment started, check log for any errors in this process!",
+                      pw.l2Tunnel().tunnelId());
+            l2TunnelId = pw.l2Tunnel().tunnelId();
+            // The tunnel id cannot be 0.
+            if (l2TunnelId == 0) {
+                log.warn("Tunnel id id must be > 0 in {}", l2TunnelId);
                 return Result.WRONG_PARAMETERS
-                        .appendError("Can not deploy pseudowire from spine to spine!");
-            } else if (srManager.deviceConfiguration().isEdgeDevice(cp1.deviceId()) &&
-                    srManager.deviceConfiguration().isEdgeDevice(cp2.deviceId())) {
-                leafSpinePw = false;
-            } else {
-                leafSpinePw = true;
+                        .appendError("Tunnel id id must be > 0");
             }
-        } catch (DeviceConfigNotFoundException e) {
-            log.error("Device for pseudowire connection points does not exist in the configuration");
-            return Result.INTERNAL_ERROR
-                    .appendError("Device for pseudowire connection points does not exist in the configuration");
+
+            result = verifyGlobalValidity(pw);
+            if (result != SUCCESS) {
+                log.error("Global validity for pseudowire {} is wrong!", l2TunnelId);
+                return result;
+            }
+
+            // leafSpinePw determines if this is a leaf-leaf
+            // or leaf-spine pseudowire
+            boolean leafSpinePw;
+            ConnectPoint cp1 = pw.l2TunnelPolicy().cP1();
+            ConnectPoint cp2 = pw.l2TunnelPolicy().cP2();
+            try {
+                // differentiate between leaf-leaf pseudowires and leaf-spine
+                if (!srManager.deviceConfiguration().isEdgeDevice(cp1.deviceId()) &&
+                        !srManager.deviceConfiguration().isEdgeDevice(cp2.deviceId())) {
+                    log.error("Can not deploy pseudowire {} from spine to spine!", l2TunnelId);
+                    return Result.WRONG_PARAMETERS
+                            .appendError("Can not deploy pseudowire from spine to spine!");
+                } else if (srManager.deviceConfiguration().isEdgeDevice(cp1.deviceId()) &&
+                        srManager.deviceConfiguration().isEdgeDevice(cp2.deviceId())) {
+                    leafSpinePw = false;
+                } else {
+                    leafSpinePw = true;
+                }
+            } catch (DeviceConfigNotFoundException e) {
+                log.error("Device for pseudowire {} connection points does not exist in the configuration", l2TunnelId);
+                return Result.INTERNAL_ERROR
+                        .appendError("Device for pseudowire connection points does not exist in the configuration");
+            }
+
+            // reverse the policy in order for leaf switch to be at CP1
+            // this will help us for re-using SRLinkWeigher for computing valid paths
+            L2TunnelPolicy reversedPolicy = reverseL2TunnelPolicy(pw.l2TunnelPolicy());
+            if (reversedPolicy == null) {
+                log.error("Error in reversing policy, device configuration was not found for pseudowire {}.",
+                          l2TunnelId);
+                return INTERNAL_ERROR
+                        .appendError("Device configuration not found when reversing the policy.");
+            }
+            pw.setL2TunnelPolicy(reversedPolicy);
+
+            // get path here, need to use the same for fwd and rev direction
+            List<Link> path = getPath(pw.l2TunnelPolicy().cP1(),
+                                      pw.l2TunnelPolicy().cP2());
+            if (path == null) {
+                log.error("Deploying process : No path between the connection points for pseudowire {}", l2TunnelId);
+                return PATH_NOT_FOUND.appendError("No path between the connection points for pseudowire!");
+            }
+
+            Link fwdNextHop;
+            Link revNextHop;
+            if (!isValidPath(path, leafSpinePw)) {
+                log.error("Deploying process : Path for pseudowire {} is not valid", l2TunnelId);
+                return INTERNAL_ERROR.appendError("Internal error : path for pseudowire is not valid!");
+            }
+            // oneHope flag is used to determine if we need to
+            // install transit mpls rules
+            boolean oneHop = true;
+            if (path.size() > 1) {
+                oneHop = false;
+            }
+
+            fwdNextHop = path.get(0);
+            revNextHop = reverseLink(path.get(path.size() - 1));
+
+            pw.l2Tunnel().setPath(path);
+            pw.l2Tunnel().setTransportVlan(determineTransportVlan(leafSpinePw));
+
+            // next hops for next objectives
+            log.info("Deploying process : Establishing forward direction for pseudowire {}", l2TunnelId);
+
+            VlanId egressVlan = determineEgressVlan(pw.l2TunnelPolicy().cP1OuterTag(),
+                                                    pw.l2TunnelPolicy().cP1InnerTag(),
+                                                    pw.l2TunnelPolicy().cP2OuterTag(),
+                                                    pw.l2TunnelPolicy().cP2InnerTag());
+            result = deployPseudoWireInit(pw.l2Tunnel(),
+                                          pw.l2TunnelPolicy().cP1(),
+                                          pw.l2TunnelPolicy().cP2(),
+                                          FWD,
+                                          fwdNextHop,
+                                          leafSpinePw,
+                                          oneHop,
+                                          egressVlan);
+            if (result != SUCCESS) {
+                log.error("Deploying process : Error in deploying pseudowire {} initiation for CP1", l2TunnelId);
+                return Result.INTERNAL_ERROR.appendError("Error in deploying pseudowire initiation for CP1");
+            }
+
+            result = deployPolicy(l2TunnelId,
+                                  pw.l2TunnelPolicy().cP1(),
+                                  pw.l2TunnelPolicy().cP1InnerTag(),
+                                  pw.l2TunnelPolicy().cP1OuterTag(),
+                                  egressVlan,
+                                  result.getNextId());
+            if (result != SUCCESS) {
+                log.error("Deploying process : Error in deploying pseudowire {} policy for CP1", l2TunnelId);
+                return Result.INTERNAL_ERROR.appendError("Error in deploying pseudowire policy for CP1");
+            }
+
+            PortNumber termPort = pw.l2Tunnel().pathUsed().get(pw.l2Tunnel().pathUsed().size() - 1).dst().port();
+            result = deployPseudoWireTerm(pw.l2Tunnel(),
+                                          pw.l2TunnelPolicy().cP2(),
+                                          egressVlan,
+                                          FWD,
+                                          leafSpinePw,
+                                          oneHop,
+                                          termPort);
+
+            if (result != SUCCESS) {
+                log.error("Deploying process : Error in deploying pseudowire {} termination for CP1", l2TunnelId);
+                return Result.INTERNAL_ERROR.appendError("Error in deploying pseudowire termination for CP1");
+            }
+
+            // We establish the reverse tunnel.
+            log.info("Deploying process : Establishing reverse direction for pseudowire {}", l2TunnelId);
+            egressVlan = determineEgressVlan(pw.l2TunnelPolicy().cP2OuterTag(),
+                                             pw.l2TunnelPolicy().cP2InnerTag(),
+                                             pw.l2TunnelPolicy().cP1OuterTag(),
+                                             pw.l2TunnelPolicy().cP1InnerTag());
+
+            result = deployPseudoWireInit(pw.l2Tunnel(),
+                                          pw.l2TunnelPolicy().cP2(),
+                                          pw.l2TunnelPolicy().cP1(),
+                                          REV,
+                                          revNextHop,
+                                          leafSpinePw,
+                                          oneHop,
+                                          egressVlan);
+            if (result != SUCCESS) {
+                log.error("Deploying process : Error in deploying pseudowire {} initiation for CP2", l2TunnelId);
+                return Result.INTERNAL_ERROR
+                        .appendError("Error in deploying pseudowire initiation for CP2");
+            }
+
+            result = deployPolicy(l2TunnelId,
+                                  pw.l2TunnelPolicy().cP2(),
+                                  pw.l2TunnelPolicy().cP2InnerTag(),
+                                  pw.l2TunnelPolicy().cP2OuterTag(),
+                                  egressVlan,
+                                  result.getNextId());
+            if (result != SUCCESS) {
+                log.error("Deploying process : Error in deploying policy {} for CP2", l2TunnelId);
+                return Result.INTERNAL_ERROR
+                        .appendError("Deploying process : Error in deploying policy for CP2");
+            }
+
+            termPort = pw.l2Tunnel().pathUsed().get(0).src().port();
+            result = deployPseudoWireTerm(pw.l2Tunnel(),
+                                          pw.l2TunnelPolicy().cP1(),
+                                          egressVlan,
+                                          REV,
+                                          leafSpinePw,
+                                          oneHop,
+                                          termPort);
+
+            if (result != SUCCESS) {
+                log.error("Deploying process : Error in deploying pseudowire {} termination for CP2", l2TunnelId);
+                return Result.INTERNAL_ERROR.appendError("Error in deploying pseudowire termination for CP2");
+            }
+
+            result = manageIntermediateFiltering(pw, leafSpinePw);
+            if (result != SUCCESS) {
+                log.error("Deploying process : Error in installing intermediate rules for " +
+                                  "tagged transport for pseudowire {}", l2TunnelId);
+                return Result.INTERNAL_ERROR.appendError("Error in installing intermediate rules for tagged transport");
+            }
+
+            log.info("Deploying process : Updating relevant information for pseudowire {}", l2TunnelId);
+
+            // Populate stores as the final step of the process
+            l2TunnelStore.put(Long.toString(l2TunnelId), pw.l2Tunnel());
+            l2PolicyStore.put(Long.toString(l2TunnelId), pw.l2TunnelPolicy());
+
+            return Result.SUCCESS;
+        } catch (StorageException.Timeout e) {
+            log.error("Can not acquire distributed lock for pseudowire {}!", pw.l2Tunnel().tunnelId());
+            return Result.INTERNAL_ERROR.appendError("Can not acquire distributed lock!");
+        } finally {
+            // release the lock
+            pwLock.unlock();
         }
-
-        // reverse the policy in order for leaf switch to be at CP1
-        // this will help us for re-using SRLinkWeigher for computing valid paths
-        L2TunnelPolicy reversedPolicy = reverseL2TunnelPolicy(pw.l2TunnelPolicy());
-        if (reversedPolicy == null) {
-            log.error("Error in reversing policy, device configuration was not found!");
-            return  INTERNAL_ERROR
-                    .appendError("Device configuration not found when reversing the policy.");
-        }
-        pw.setL2TunnelPolicy(reversedPolicy);
-
-        // get path here, need to use the same for fwd and rev direction
-        List<Link> path = getPath(pw.l2TunnelPolicy().cP1(),
-                                  pw.l2TunnelPolicy().cP2());
-        if (path == null) {
-            log.error("Deploying process : No path between the connection points for pseudowire {}", l2TunnelId);
-            return PATH_NOT_FOUND.appendError("No path between the connection points for pseudowire!");
-        }
-
-        Link fwdNextHop;
-        Link revNextHop;
-        if (!isValidPath(path, leafSpinePw)) {
-            log.error("Deploying process : Path for pseudowire {} is not valid",
-                      l2TunnelId);
-            return INTERNAL_ERROR.appendError("Internal error : path for pseudowire is not valid!");
-        }
-
-        // oneHope flag is used to determine if we need to
-        // install transit mpls rules
-        boolean oneHop = true;
-        if (path.size() > 1) {
-            oneHop = false;
-        }
-
-        fwdNextHop = path.get(0);
-        revNextHop = reverseLink(path.get(path.size() - 1));
-
-        pw.l2Tunnel().setPath(path);
-        pw.l2Tunnel().setTransportVlan(determineTransportVlan(leafSpinePw));
-
-        // next hops for next objectives
-        log.info("Deploying process : Establishing forward direction for pseudowire {}", l2TunnelId);
-
-        VlanId egressVlan = determineEgressVlan(pw.l2TunnelPolicy().cP1OuterTag(),
-                                                pw.l2TunnelPolicy().cP1InnerTag(),
-                                                pw.l2TunnelPolicy().cP2OuterTag(),
-                                                pw.l2TunnelPolicy().cP2InnerTag());
-        // We establish the tunnel.
-        // result.nextId will be used in fwd
-        result = deployPseudoWireInit(pw.l2Tunnel(),
-                                      pw.l2TunnelPolicy().cP1(),
-                                      pw.l2TunnelPolicy().cP2(),
-                                      FWD,
-                                      fwdNextHop,
-                                      leafSpinePw,
-                                      oneHop,
-                                      egressVlan);
-        if (result != SUCCESS) {
-            log.info("Deploying process : Error in deploying pseudowire initiation for CP1");
-            return Result.INTERNAL_ERROR.appendError("Error in deploying pseudowire initiation for CP1");
-        }
-
-        // We create the policy.
-        result = deployPolicy(l2TunnelId,
-                              pw.l2TunnelPolicy().cP1(),
-                              pw.l2TunnelPolicy().cP1InnerTag(),
-                              pw.l2TunnelPolicy().cP1OuterTag(),
-                              egressVlan,
-                              result.getNextId());
-        if (result != SUCCESS) {
-            log.info("Deploying process : Error in deploying pseudowire policy for CP1");
-            return Result.INTERNAL_ERROR.appendError("Error in deploying pseudowire policy for CP1");
-        }
-
-        // We terminate the tunnel
-        result = deployPseudoWireTerm(pw.l2Tunnel(),
-                                       pw.l2TunnelPolicy().cP2(),
-                                       egressVlan,
-                                       FWD,
-                                       leafSpinePw,
-                                       oneHop);
-
-        if (result != SUCCESS) {
-            log.info("Deploying process : Error in deploying pseudowire termination for CP1");
-            return Result.INTERNAL_ERROR.appendError("Error in deploying pseudowire termination for CP1");
-        }
-
-        log.info("Deploying process : Establishing reverse direction for pseudowire {}", l2TunnelId);
-
-        egressVlan = determineEgressVlan(pw.l2TunnelPolicy().cP2OuterTag(),
-                                         pw.l2TunnelPolicy().cP2InnerTag(),
-                                         pw.l2TunnelPolicy().cP1OuterTag(),
-                                         pw.l2TunnelPolicy().cP1InnerTag());
-
-        // We establish the reverse tunnel.
-        result = deployPseudoWireInit(pw.l2Tunnel(),
-                                       pw.l2TunnelPolicy().cP2(),
-                                       pw.l2TunnelPolicy().cP1(),
-                                       REV,
-                                       revNextHop,
-                                       leafSpinePw,
-                                       oneHop,
-                                       egressVlan);
-        if (result != SUCCESS) {
-            log.info("Deploying process : Error in deploying pseudowire initiation for CP2");
-            return Result.INTERNAL_ERROR
-                    .appendError("Error in deploying pseudowire initiation for CP2");
-        }
-
-
-        result = deployPolicy(l2TunnelId,
-                               pw.l2TunnelPolicy().cP2(),
-                               pw.l2TunnelPolicy().cP2InnerTag(),
-                               pw.l2TunnelPolicy().cP2OuterTag(),
-                               egressVlan,
-                               result.getNextId());
-        if (result != SUCCESS) {
-            log.info("Deploying process : Error in deploying policy for CP2");
-            return Result.INTERNAL_ERROR
-                    .appendError("Deploying process : Error in deploying policy for CP2");
-        }
-
-        result = deployPseudoWireTerm(pw.l2Tunnel(),
-                                      pw.l2TunnelPolicy().cP1(),
-                                      egressVlan,
-                                      REV,
-                                      leafSpinePw,
-                                      oneHop);
-
-        if (result != SUCCESS) {
-            log.info("Deploying process : Error in deploying pseudowire termination for CP2");
-            return Result.INTERNAL_ERROR.appendError("Error in deploying pseudowire termination for CP2");
-        }
-
-        result = manageIntermediateFiltering(pw, leafSpinePw);
-        if (result != SUCCESS) {
-            log.info("Deploying process : Error in installing intermediate rules for tagged transport");
-            return Result.INTERNAL_ERROR.appendError("Error in installing intermediate rules for tagged transport");
-        }
-
-        log.info("Deploying process : Updating relevant information for pseudowire {}", l2TunnelId);
-
-        // Populate stores as the final step of the process
-        l2TunnelStore.put(Long.toString(l2TunnelId), pw.l2Tunnel());
-        l2PolicyStore.put(Long.toString(l2TunnelId), pw.l2TunnelPolicy());
-
-        return Result.SUCCESS;
     }
 
     @Override
@@ -760,7 +779,7 @@
         CompletableFuture<ObjectiveError> revTermNextFuture = new CompletableFuture<>();
 
         if (l2TunnelId == 0) {
-            log.warn("Removal process : Tunnel id cannot be 0");
+            log.error("Removal process : Tunnel id cannot be 0");
             return Result.WRONG_PARAMETERS.appendError("Pseudowire id can not be 0.");
         }
 
@@ -825,10 +844,13 @@
 
             fwdTermNextFuture.thenAcceptAsync(status -> {
                 if (status == null) {
+                    PortNumber termPort = pwToRemove.l2Tunnel().pathUsed()
+                            .get(pwToRemove.l2Tunnel().pathUsed().size() - 1).dst().port();
                     tearDownPseudoWireTerm(pwToRemove.l2Tunnel(),
                                            pwToRemove.l2TunnelPolicy().cP2(),
                                            null,
-                                           FWD);
+                                           FWD,
+                                           termPort);
                 }
             });
         }
@@ -861,10 +883,12 @@
 
             revTermNextFuture.thenAcceptAsync(status -> {
                 if (status == null) {
+                    PortNumber termPort = pwToRemove.l2Tunnel().pathUsed().get(0).src().port();
                     tearDownPseudoWireTerm(pwToRemove.l2Tunnel(),
                                            pwToRemove.l2TunnelPolicy().cP1(),
                                            null,
-                                           REV);
+                                           REV,
+                                           termPort);
                 }
             });
         }
@@ -883,14 +907,25 @@
      */
     public Result tearDownPseudowire(long l2TunnelId) {
 
-        if (checkIfPwExists(l2TunnelId, true) == Result.SUCCESS) {
-            return tearDownConnectionPoints(l2TunnelId, true, true, true);
-        } else if (checkIfPwExists(l2TunnelId, false) == Result.SUCCESS) {
-            return tearDownConnectionPoints(l2TunnelId, true, true, false);
-        } else {
-            return Result.WRONG_PARAMETERS.appendError("Pseudowire with "
-                                                        + l2TunnelId
-                                                        + " did not reside in any store!");
+        try {
+            // take the lock
+            pwLock.lock();
+
+            if (checkIfPwExists(l2TunnelId, true) == Result.SUCCESS) {
+                return tearDownConnectionPoints(l2TunnelId, true, true, true);
+            } else if (checkIfPwExists(l2TunnelId, false) == Result.SUCCESS) {
+                return tearDownConnectionPoints(l2TunnelId, true, true, false);
+            } else {
+                return Result.WRONG_PARAMETERS.appendError("Pseudowire with "
+                                                                   + l2TunnelId
+                                                                   + " did not reside in any store!");
+            }
+        } catch (StorageException.Timeout e) {
+            log.error("Can not acquire distributed lock for pseudowire {}!", l2TunnelId);
+            return Result.INTERNAL_ERROR.appendError("Can not acquire distributed lock!");
+        } finally {
+            // release the lock
+            pwLock.unlock();
         }
     }
 
@@ -918,16 +953,17 @@
      * @param ingress      the ingress point
      * @param ingressInner the ingress inner tag
      * @param ingressOuter the ingress outer tag
-     * @param nextId       the next objective id
      * @param egressVlan   Vlan-id to set, depends on ingress vlan
      *                     combinations. For example, if pw is double tagged
      *                     then this is the value of the outer vlan, if single
      *                     tagged then it is the new value of the single tag.
      *                     Should be None for untagged traffic.
+     * @param nextId       the next objective id
      * @return the result of the operation
      */
     private Result deployPolicy(long tunnelId, ConnectPoint ingress, VlanId ingressInner,
                                 VlanId ingressOuter, VlanId egressVlan, int nextId) {
+        log.debug("Starting deploying policy for pseudowire {}.", tunnelId);
 
         List<Objective> objectives = Lists.newArrayList();
         // We create the forwarding objective for supporting
@@ -937,8 +973,9 @@
         ObjectiveContext context = new DefaultObjectiveContext((objective) ->
                                                                 log.debug("FwdObj for tunnel {} populated", tunnelId),
                                                                (objective, error) ->
-                                                                log.warn("Failed to populate fwdrObj " +
-                                                                                 "for tunnel {}", tunnelId, error));
+                                                                log.warn("Failed to populate fwdObj " +
+                                                                                 "for tunnel {} : {}",
+                                                                         tunnelId, error));
         objectives.add(fwdBuilder.add(context));
 
         // We create the filtering objective to define the
@@ -955,7 +992,8 @@
         // 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));
+                                                                                     "tunnel {} : {}",
+                                                                             tunnelId, error));
         objectives.add(filtBuilder.add(context));
 
         for (Objective objective : objectives) {
@@ -984,9 +1022,10 @@
     private Result deployPseudoWireInit(L2Tunnel l2Tunnel, ConnectPoint ingress,
                                         ConnectPoint egress, Direction direction,
                                         Link nextHop, boolean spinePw, boolean oneHop, VlanId termVlanId) {
-
+        log.debug("Started deploying init next objectives for pseudowire {} for tunnel {} -> {}.",
+                  l2Tunnel.tunnelId(), ingress, egress);
         if (nextHop == null) {
-            log.warn("No path between ingress and egress cps for tunnel {}", l2Tunnel.tunnelId());
+            log.warn("No path between ingress and egress connection points for tunnel {}", l2Tunnel.tunnelId());
             return WRONG_PARAMETERS;
         }
 
@@ -1046,10 +1085,15 @@
      * @param egressVlan the expected vlan at egress
      * @param direction  the direction
      * @param spinePw if the pseudowire involves a spine switch
+     * @param inputTermPort the input port at the termination point for the pseudowire, used for installing special
+     *                      filtering rules at the termination
      * @return the result of the operation
      */
     private Result deployPseudoWireTerm(L2Tunnel l2Tunnel, ConnectPoint egress,
-                                        VlanId egressVlan, Direction direction, boolean spinePw, boolean oneHop) {
+                                        VlanId egressVlan, Direction direction,
+                                        boolean spinePw, boolean oneHop, PortNumber inputTermPort) {
+        log.debug("Started deploying termination objectives for pseudowire {} , direction {}.",
+                  l2Tunnel.tunnelId(), direction == FWD ? "forward" : "reverse");
 
         // We create the group relative to the termination.
         NextObjective.Builder nextObjectiveBuilder = createNextObjective(TERMINATION, egress, null,
@@ -1092,7 +1136,7 @@
         context = new DefaultObjectiveContext((objective) -> log.debug("FwdObj for tunnel termination {} populated",
                                                                        l2Tunnel.tunnelId()),
                                               (objective, error) -> log.warn("Failed to populate fwdrObj" +
-                                                                             " for tunnel termination {}",
+                                                                             " 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 {}",
@@ -1100,16 +1144,6 @@
 
         if (spinePw) {
 
-            // determine the input port at the
-            PortNumber inPort;
-
-            if (egress.deviceId().
-                    equals(l2Tunnel.pathUsed().get(0).dst().deviceId())) {
-                    inPort = l2Tunnel.pathUsed().get(0).dst().port();
-            } else {
-                    inPort = l2Tunnel.pathUsed().get(0).src().port();
-            }
-
             MacAddress dstMac;
             try {
                 dstMac = srManager.deviceConfiguration().getDeviceMac(egress.deviceId());
@@ -1121,10 +1155,10 @@
             log.info("Populating filtering objective for pseudowire transport" +
                              " with vlan = {}, port = {}, mac = {}",
                      l2Tunnel.transportVlan(),
-                     inPort,
+                     inputTermPort,
                      dstMac);
             FilteringObjective.Builder filteringObjectiveBuilder =
-                    createNormalPipelineFiltObjective(inPort, l2Tunnel.transportVlan(), dstMac);
+                    createNormalPipelineFiltObjective(inputTermPort, l2Tunnel.transportVlan(), dstMac);
             context = new DefaultObjectiveContext(( objective ) ->
                                                           log.debug("Special filtObj for  " + "for {} populated",
                                                                     l2Tunnel.tunnelId()),
@@ -1138,7 +1172,7 @@
             srManager.flowObjectiveService.filter(egress.deviceId(), filteringObjectiveBuilder.add(context));
             log.debug("Creating new special FiltObj for termination point with tunnel {} for port {}",
                       l2Tunnel.tunnelId(),
-                      inPort);
+                      inputTermPort);
         }
 
         return SUCCESS;
@@ -1156,7 +1190,7 @@
                                                                          VlanId vlanId,
                                                                          MacAddress dstMac) {
 
-        log.info("Creating filtering objective for pseudowire transport with vlan={}, port={}, mac={}",
+        log.debug("Creating filtering objective for pseudowire intermediate transport with vlan={}, port={}, mac={}",
                  vlanId,
                  inPort,
                  dstMac);
@@ -1185,7 +1219,7 @@
      */
     private FilteringObjective.Builder createFiltObjective(PortNumber inPort, VlanId innerTag, VlanId outerTag) {
 
-        log.info("Creating filtering objective for vlans {} / {}", outerTag, innerTag);
+        log.debug("Creating connection point filtering objective for vlans {} / {}", outerTag, innerTag);
         return DefaultFilteringObjective
                 .builder()
                 .withKey(Criteria.matchInPort(inPort))
@@ -1208,6 +1242,8 @@
     private ForwardingObjective.Builder createTermFwdObjective(MplsLabel pwLabel, long tunnelId,
                                                                PortNumber egressPort, int nextId) {
 
+        log.debug("Creating forwarding objective for termination for tunnel {} : pwLabel {}, egressPort {}, nextId {}",
+                 tunnelId, pwLabel, egressPort, nextId);
         TrafficSelector.Builder trafficSelector = DefaultTrafficSelector.builder();
         TrafficTreatment.Builder trafficTreatment = DefaultTrafficTreatment.builder();
         // The flow has to match on the pw label and bos
@@ -1243,6 +1279,7 @@
      */
     private ForwardingObjective.Builder createInitFwdObjective(long tunnelId, PortNumber inPort, int nextId) {
 
+        log.debug("Creating forwarding objective for tunnel {} : Port {} , nextId {}", tunnelId, inPort, nextId);
         TrafficSelector.Builder trafficSelector = DefaultTrafficSelector.builder();
 
         // The flow has to match on the mpls logical
@@ -1281,6 +1318,9 @@
                                                       ConnectPoint dstCp,  L2Tunnel l2Tunnel,
                                                       DeviceId egressId, boolean leafSpinePw,
                                                       boolean oneHop, VlanId termVlanId) {
+        log.debug("Creating {} next objective for pseudowire {}.",
+                  pipeline == TERMINATION ? "termination" : "inititation");
+
         NextObjective.Builder nextObjBuilder;
         TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
         if (pipeline == INITIATION) {
@@ -1291,7 +1331,7 @@
             // 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");
+                log.error("Pw label not configured");
                 return null;
             }
             treatmentBuilder.pushMpls();
@@ -1317,7 +1357,7 @@
                     srLabel = MplsLabel.mplsLabel(srManager.deviceConfiguration().getPWRoutingLabel(egressId));
 
                 } catch (DeviceConfigNotFoundException e) {
-                    log.warn("Sr label for pw traffic not configured");
+                    log.error("Sr label for pw traffic not configured");
                     return null;
                 }
 
@@ -1332,7 +1372,7 @@
             try {
                 ingressMac = srManager.deviceConfiguration().getDeviceMac(srcCp.deviceId());
             } catch (DeviceConfigNotFoundException e) {
-                log.warn("Was not able to find the ingress mac");
+                log.error("Was not able to find the ingress mac");
                 return null;
             }
             treatmentBuilder.setEthSrc(ingressMac);
@@ -1340,7 +1380,7 @@
             try {
                 neighborMac = srManager.deviceConfiguration().getDeviceMac(dstCp.deviceId());
             } catch (DeviceConfigNotFoundException e) {
-                log.warn("Was not able to find the neighbor mac");
+                log.error("Was not able to find the neighbor mac");
                 return null;
             }
             treatmentBuilder.setEthDst(neighborMac);
@@ -1348,7 +1388,7 @@
             // if true we need to pop the vlan because
             // we instantiate a leaf to leaf pseudowire
             if (!leafSpinePw) {
-                log.info("We should carry this traffic UNTAGGED!");
+                log.debug("We should carry traffic UNTAGGED for pseudowire {}", l2Tunnel.tunnelId());
                 treatmentBuilder.popVlan();
             }
 
@@ -1385,6 +1425,8 @@
      *         current SRLinkWeigher
      */
     private L2TunnelPolicy reverseL2TunnelPolicy(L2TunnelPolicy policy) {
+
+        log.debug("Reversing policy for pseudowire.");
         try {
             // if cp1 is a leaf, just return
             if (srManager.deviceConfiguration().isEdgeDevice(policy.cP1().deviceId())) {
@@ -1469,7 +1511,7 @@
 
         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);
+            log.error("Abort delete of policy for tunnel {}: next does not exist in the store", tunnelId);
             if (future != null) {
                 future.complete(null);
             }
@@ -1491,7 +1533,7 @@
 
             @Override
             public void onError(Objective objective, ObjectiveError error) {
-                log.warn("Failed to remove previous fwdObj for policy {}: {}", tunnelId, error);
+                log.error("Failed to remove previous fwdObj for policy {}: {}", tunnelId, error);
                 if (future != null) {
                     future.complete(error);
                 }
@@ -1531,10 +1573,11 @@
      */
     private void tearDownPseudoWireInit(long l2TunnelId, ConnectPoint ingress,
                                         CompletableFuture<ObjectiveError> future, Direction direction) {
-
+        log.debug("Starting tearing dowing initation of pseudowire {} for direction {}.",
+                  l2TunnelId, direction == FWD ? "forward" : "reverse");
         String key = generateKey(l2TunnelId, direction);
         if (!l2InitiationNextObjStore.containsKey(key)) {
-            log.info("Abort delete of {} for {}: next does not exist in the store", INITIATION, key);
+            log.error("Abort delete of {} for {}: next does not exist in the store", INITIATION, key);
             if (future != null) {
                 future.complete(null);
             }
@@ -1581,11 +1624,13 @@
     private void tearDownPseudoWireTerm(L2Tunnel l2Tunnel,
                                         ConnectPoint egress,
                                         CompletableFuture<ObjectiveError> future,
-                                        Direction direction) {
-
+                                        Direction direction,
+                                        PortNumber inPort) {
+        log.debug("Starting tearing down termination for pseudowire {} direction {}.",
+                  l2Tunnel.tunnelId(), direction == FWD ? "forward" : "reverse");
         String key = generateKey(l2Tunnel.tunnelId(), direction);
         if (!l2TerminationNextObjStore.containsKey(key)) {
-            log.info("Abort delete of {} for {}: next does not exist in the store", TERMINATION, key);
+            log.error("Abort delete of {} for {}: next does not exist in the store", TERMINATION, key);
             if (future != null) {
                 future.complete(null);
             }
@@ -1640,21 +1685,11 @@
         // spine-spine pws
         if (!l2Tunnel.transportVlan().equals(UNTAGGED_TRANSPORT_VLAN)) {
 
-            // determine the input port at the
-            PortNumber inPort;
-
-            if (egress.deviceId().
-                    equals(l2Tunnel.pathUsed().get(0).dst().deviceId())) {
-                inPort = l2Tunnel.pathUsed().get(0).dst().port();
-            } else {
-                inPort = l2Tunnel.pathUsed().get(0).src().port();
-            }
-
             MacAddress dstMac;
             try {
                 dstMac = srManager.deviceConfiguration().getDeviceMac(egress.deviceId());
             } catch (Exception e) {
-                log.info("Device not found in configuration, no programming of MAC address");
+                log.error("Device not found in configuration, no programming of MAC address");
                 dstMac = null;
             }
 
@@ -1667,9 +1702,11 @@
                     createNormalPipelineFiltObjective(inPort, l2Tunnel.transportVlan(), dstMac);
             context = new DefaultObjectiveContext(( objective ) ->
                                                           log.debug("Special filtObj for  " + "for {} removed",
-                                                                    l2Tunnel.tunnelId()), ( objective, error ) ->
-                    log.warn("Failed to populate " + "special filtObj " +
-                                     "rule for {}: {}", l2Tunnel.tunnelId(), error));
+                                                                    l2Tunnel.tunnelId()),
+                                                  ( objective, error ) ->
+                                                          log.warn("Failed to populate " + "special filtObj " +
+                                                                           "rule for {}: {}",
+                                                                   l2Tunnel.tunnelId(), error));
             TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
             filteringObjectiveBuilder.withMeta(treatment.build());
             srManager.flowObjectiveService.filter(egress.deviceId(), filteringObjectiveBuilder.remove(context));
@@ -1692,5 +1729,4 @@
     private String generateKey(long tunnelId, Direction direction) {
         return String.format("%s-%s", tunnelId, direction);
     }
-
 }
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/PwaasUtil.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/PwaasUtil.java
index f4a71ab..1475198 100644
--- a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/PwaasUtil.java
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/PwaasUtil.java
@@ -32,6 +32,8 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import static com.google.common.base.Preconditions.checkArgument;
+
 /**
  * Utility class with static methods that help
  * parse pseudowire related information and also
@@ -63,12 +65,7 @@
         } else if (vlan.equals("") || vlan.equals("None")) {
             return VlanId.vlanId("None");
         } else {
-            try {
-                VlanId newVlan = VlanId.vlanId(vlan);
-                return newVlan;
-            } catch (IllegalArgumentException e) {
-                return null;
-            }
+            return VlanId.vlanId(vlan);
         }
     }
 
@@ -78,11 +75,8 @@
      * @return the L2Mode if input is correct
      */
     public static L2Mode parseMode(String mode) {
-
-        if (!mode.equals("RAW") && !mode.equals("TAGGED")) {
-            return null;
-        }
-
+        checkArgument(mode.equals("RAW") || mode.equals("TAGGED"),
+                      "Invalid pseudowire mode of operation, should be TAGGED or RAW.");
         return L2Mode.valueOf(mode);
     }
 
@@ -93,13 +87,7 @@
      * @throws IllegalArgumentException if label is invalid
      */
     public static MplsLabel parsePWLabel(String label) {
-
-        try {
-            MplsLabel pwLabel = MplsLabel.mplsLabel(label);
-            return pwLabel;
-        } catch (Exception e) {
-            return null;
-        }
+        return MplsLabel.mplsLabel(label);
     }
 
     /**
@@ -109,14 +97,9 @@
      * @return The id of pw as an Integer or null if it failed the conversion.
      */
     public static Integer parsePwId(String id) {
-        try {
-            return Integer.parseInt(id);
-        } catch (Exception e) {
-            return null;
-        }
+        return Integer.parseInt(id);
     }
 
-
     /**
      * Helper method to verify if the tunnel is whether or not
      * supported.
diff --git a/apps/segmentrouting/web/src/main/java/org/onosproject/segmentrouting/web/PseudowireCodec.java b/apps/segmentrouting/web/src/main/java/org/onosproject/segmentrouting/web/PseudowireCodec.java
index 00d20a7..8abfa71 100644
--- a/apps/segmentrouting/web/src/main/java/org/onosproject/segmentrouting/web/PseudowireCodec.java
+++ b/apps/segmentrouting/web/src/main/java/org/onosproject/segmentrouting/web/PseudowireCodec.java
@@ -15,6 +15,7 @@
  */
 package org.onosproject.segmentrouting.web;
 
+import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.node.ArrayNode;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import org.apache.commons.lang3.tuple.Pair;
@@ -27,9 +28,11 @@
 import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelDescription;
 import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelPolicy;
 import org.onosproject.segmentrouting.pwaas.L2Mode;
+import org.onosproject.segmentrouting.pwaas.L2TunnelDescription;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.ArrayList;
 import java.util.List;
 
 import static org.onosproject.segmentrouting.pwaas.PwaasUtil.*;
@@ -69,13 +72,11 @@
 
         result.put(CP1_INNER_TAG, pseudowire.l2TunnelPolicy().cP1InnerTag().toString());
         result.put(CP1_OUTER_TAG, pseudowire.l2TunnelPolicy().cP1OuterTag().toString());
-
-
         result.put(CP2_INNER_TAG, pseudowire.l2TunnelPolicy().cP2InnerTag().toString());
         result.put(CP2_OUTER_TAG, pseudowire.l2TunnelPolicy().cP2OuterTag().toString());
+        result.put(SERVICE_DELIM_TAG, pseudowire.l2Tunnel().sdTag().toString());
 
         result.put(MODE, pseudowire.l2Tunnel().pwMode() == L2Mode.RAW ? "RAW" : "TAGGED");
-        result.put(SERVICE_DELIM_TAG, pseudowire.l2Tunnel().sdTag().toString());
         result.put(PW_LABEL, pseudowire.l2Tunnel().pwLabel().toString());
 
         return result;
@@ -101,25 +102,77 @@
     }
 
     /**
-     * Returns a JSON containing the failed pseudowires and the reason that its one failed.
+     * Encoded in an Object Node the undecoed pseudowire and the specificError it failed.
+     *
+     * @param failedPW The failed pseudowire in json format
+     * @param specificError The specificError it failed
+     * @param context Our context
+     * @return A node containing the information we provided
+     */
+    public ObjectNode encodeError(JsonNode failedPW, String specificError,
+                                  CodecContext context) {
+        ObjectNode result = context.mapper().createObjectNode();
+
+        result.set(FAILED_PW, failedPW);
+        result.put(REASON, specificError);
+
+        return result;
+    }
+
+    /**
+     * Returns a JSON containing the failed pseudowires and the reason that they failed.
      *
      * @param failedPws Pairs of pws and reasons.
+     * @param undecodedPws Pairs of pws that we could not decode with reason being illegal arguments.
      * @param context The context
      * @return ObjectNode representing the json to return
      */
     public ObjectNode encodeFailedPseudowires(
             List<Pair<DefaultL2TunnelDescription, String>> failedPws,
+            List<Pair<JsonNode, String>> undecodedPws,
             CodecContext context) {
 
         ArrayNode failedNodes = context.mapper().createArrayNode();
         failedPws.stream()
                 .forEach(failed -> failedNodes.add(encodeError(failed.getKey(), failed.getValue(), context)));
+        undecodedPws.stream()
+                .forEach(failed -> failedNodes.add(encodeError(failed.getKey(), failed.getValue(), context)));
         final ObjectNode toReturn = context.mapper().createObjectNode();
         toReturn.set(FAILED_PWS, failedNodes);
         return toReturn;
     }
 
     /**
+     *
+     * @param json The json containing the pseudowires.
+     * @param context The context
+     * @return A pair of lists.
+     *         First list contains pseudowires that we were not able to decode
+     *         along with the reason we could not decode them.
+     *         Second list contains successfully decoded pseudowires which we are
+     *         going to instantiate.
+     */
+    public Pair<List<Pair<JsonNode, String>>, List<L2TunnelDescription>> decodePws(ArrayNode json,
+                                                                                   CodecContext context) {
+
+        List<L2TunnelDescription> decodedPws = new ArrayList<>();
+        List<Pair<JsonNode, String>> notDecodedPws = new ArrayList<>();
+        for (JsonNode node : json) {
+            DefaultL2TunnelDescription l2Description;
+            try {
+                l2Description = decode((ObjectNode) node, context);
+                decodedPws.add(l2Description);
+            } catch (IllegalArgumentException e) {
+                // the reason why we could not decode this pseudowire is encoded in the
+                // exception, we need to store it now
+                notDecodedPws.add(Pair.of(node, e.getMessage()));
+            }
+        }
+
+        return Pair.of(notDecodedPws, decodedPws);
+    }
+
+    /**
      * Decodes a json containg a single field with the pseudowire id.
      *
      * @param json Json to decode.
@@ -127,8 +180,10 @@
      */
     public static Integer decodeId(ObjectNode json) {
 
-        Integer id = parsePwId(json.path(PW_ID).asText());
-        if (id == null) {
+        Integer id;
+        try {
+            id = parsePwId(json.path(PW_ID).asText());
+        } catch (IllegalArgumentException e) {
             log.error("Pseudowire id is not an integer!");
             return null;
         }
@@ -139,66 +194,25 @@
     @Override
     public DefaultL2TunnelDescription decode(ObjectNode json, CodecContext context) {
 
-        String tempString;
-
         Integer id = parsePwId(json.path(PW_ID).asText());
-        if (id == null) {
-            log.error("Pseudowire id is not an integer");
-            return null;
-        }
 
         ConnectPoint cP1, cP2;
-        try {
-            tempString = json.path(CP1).asText();
-            cP1 = ConnectPoint.deviceConnectPoint(tempString);
-        } catch (Exception e) {
-            log.error("cP1 is not a valid connect point!");
-            return null;
-        }
+        cP1 = ConnectPoint.deviceConnectPoint(json.path(CP1).asText());
+        cP2 = ConnectPoint.deviceConnectPoint(json.path(CP2).asText());
 
-        try {
-            tempString = json.path(CP2).asText();
-            cP2 = ConnectPoint.deviceConnectPoint(tempString);
-        } catch (Exception e) {
-            log.error("cP2 is not a valid connect point!");
-            return null;
-        }
-
-        VlanId cP1InnerVlan = parseVlan(json.path(CP1_INNER_TAG).asText());
-        VlanId cP1OuterVlan = parseVlan(json.path(CP1_OUTER_TAG).asText());
-        VlanId cP2InnerVlan = parseVlan(json.path(CP2_INNER_TAG).asText());
-        VlanId cP2OuterVlan = parseVlan(json.path(CP2_OUTER_TAG).asText());
-        if ((cP1InnerVlan == null) || (cP1OuterVlan == null) ||
-                (cP2InnerVlan == null) || (cP2OuterVlan == null)) {
-            log.error("One or more vlan for cp1 or cp2 is malformed, it shouldbe an integer / Any / None / *");
-            return null;
-        }
+        VlanId cP1InnerVlan, cP1OuterVlan, cP2InnerVlan, cP2OuterVlan, sdTag;
+        cP1InnerVlan = parseVlan(json.path(CP1_INNER_TAG).asText());
+        cP1OuterVlan = parseVlan(json.path(CP1_OUTER_TAG).asText());
+        cP2InnerVlan = parseVlan(json.path(CP2_INNER_TAG).asText());
+        cP2OuterVlan = parseVlan(json.path(CP2_OUTER_TAG).asText());
+        sdTag = parseVlan(json.path(SERVICE_DELIM_TAG).asText());
 
         L2Mode mode = parseMode(json.path(MODE).asText());
-        if (mode == null) {
-            log.error("Mode should be RAW or TAGGED!");
-            return null;
-        }
-
-        VlanId sdTag = parseVlan(json.path(SERVICE_DELIM_TAG).asText());
-        if (sdTag == null) {
-            log.error("SD tag is malformed, it should be an integer / Any / None / *");
-            return null;
-        }
-
         MplsLabel pwLabel = parsePWLabel(json.path(PW_LABEL).asText());
-        if (pwLabel == null) {
-            log.error("PW label is malformed, should be an integer!");
-            return null;
-        }
 
-        DefaultL2Tunnel l2Tunnel;
-        DefaultL2TunnelPolicy l2Policy;
-
-        l2Tunnel = new DefaultL2Tunnel(mode, sdTag, id, pwLabel);
-        l2Policy = new DefaultL2TunnelPolicy(id, cP1, cP1InnerVlan, cP1OuterVlan,
+        DefaultL2Tunnel l2Tunnel = new DefaultL2Tunnel(mode, sdTag, id, pwLabel);
+        DefaultL2TunnelPolicy l2Policy = new DefaultL2TunnelPolicy(id, cP1, cP1InnerVlan, cP1OuterVlan,
                                              cP2, cP2InnerVlan, cP2OuterVlan);
-
         return new DefaultL2TunnelDescription(l2Tunnel, l2Policy);
 
     }
diff --git a/apps/segmentrouting/web/src/main/java/org/onosproject/segmentrouting/web/PseudowireWebResource.java b/apps/segmentrouting/web/src/main/java/org/onosproject/segmentrouting/web/PseudowireWebResource.java
index 854697b..4867c90 100644
--- a/apps/segmentrouting/web/src/main/java/org/onosproject/segmentrouting/web/PseudowireWebResource.java
+++ b/apps/segmentrouting/web/src/main/java/org/onosproject/segmentrouting/web/PseudowireWebResource.java
@@ -24,6 +24,7 @@
 import org.onosproject.rest.AbstractWebResource;
 import org.onosproject.segmentrouting.SegmentRoutingService;
 import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelDescription;
+import org.onosproject.segmentrouting.pwaas.L2TunnelDescription;
 import org.onosproject.segmentrouting.pwaas.L2TunnelPolicy;
 import org.onosproject.segmentrouting.pwaas.L2Tunnel;
 import org.onosproject.segmentrouting.pwaas.L2TunnelHandler;
@@ -111,28 +112,36 @@
         ObjectMapper mapper = new ObjectMapper();
         ObjectNode pseudowireJson = readTreeFromStream(mapper, input);
         SegmentRoutingService srService = get(SegmentRoutingService.class);
+        List<Pair<DefaultL2TunnelDescription, String>> failed = new ArrayList<>();
+        List<Pair<JsonNode, String>> undecoded = new ArrayList<>();
 
-        DefaultL2TunnelDescription pseudowire = PSEUDOWIRE_CODEC.decode(pseudowireJson, this);
-        if (pseudowire == null) {
-            return Response.serverError().status(Response.Status.BAD_REQUEST).build();
+        DefaultL2TunnelDescription pseudowire;
+        try {
+            pseudowire = PSEUDOWIRE_CODEC.decode(pseudowireJson, this);
+
+            // pseudowire decoded, try to instantiate it, if we fail add it to failed list
+            long tunId = pseudowire.l2Tunnel().tunnelId();
+            log.debug("Creating pseudowire {} from rest api!", tunId);
+
+            L2TunnelHandler.Result res = srService.addPseudowire(pseudowire);
+            if (res != L2TunnelHandler.Result.SUCCESS) {
+                log.error("Could not create pseudowire {} : {}", pseudowire.l2Tunnel().tunnelId(),
+                          res.getSpecificError());
+                failed.add(Pair.of(pseudowire, res.getSpecificError()));
+            }
+        } catch (IllegalArgumentException e) {
+            log.debug("Pseudowire could not be decoded : {}", e.getMessage());
+            undecoded.add(Pair.of(pseudowireJson, e.getMessage()));
         }
 
-        long tunId = pseudowire.l2Tunnel().tunnelId();
-        log.debug("Creating pseudowire {} from rest api!", tunId);
-
-        L2TunnelHandler.Result res = srService.addPseudowire(pseudowire);
-        switch (res) {
-            case WRONG_PARAMETERS:
-            case CONFIGURATION_ERROR:
-            case PATH_NOT_FOUND:
-            case INTERNAL_ERROR:
-                log.error("Pseudowire {} could not be added : {}", tunId, res.getSpecificError());
-                return Response.serverError().status(Response.Status.INTERNAL_SERVER_ERROR).build();
-            case SUCCESS:
-                log.info("Pseudowire {} succesfully deployed!", pseudowire.l2Tunnel().tunnelId());
-                return Response.ok().build();
-            default:
-                return Response.ok().build();
+        if ((failed.size() == 0) && (undecoded.size() == 0)) {
+            // pseudowire instantiated correctly
+            return Response.ok().build();
+        } else {
+            // failed to decode or instantiate pseudowire, return the reason
+            PseudowireCodec pwCodec = new PseudowireCodec();
+            ObjectNode result = pwCodec.encodeFailedPseudowires(failed, undecoded, this);
+            return Response.serverError().entity(result).build();
         }
     }
 
@@ -152,33 +161,36 @@
         ObjectMapper mapper = new ObjectMapper();
         ObjectNode pseudowireJson = readTreeFromStream(mapper, input);
         SegmentRoutingService srService = get(SegmentRoutingService.class);
-        List<DefaultL2TunnelDescription> pseudowires;
+        Pair<List<Pair<JsonNode, String>>, List<L2TunnelDescription>> pseudowires;
 
         try {
             ArrayNode pseudowiresArray = nullIsIllegal((ArrayNode) pseudowireJson.get(PWS), PWS_KEY_ERROR);
-            pseudowires = PSEUDOWIRE_CODEC.decode(pseudowiresArray, this);
+            // get two lists, first one contains pseudowires that we were unable to decode
+            // that have faulty arguments, second one contains pseudowires that we decoded
+            // succesfully
+            pseudowires = PSEUDOWIRE_CODEC.decodePws(pseudowiresArray, this);
         } catch (ItemNotFoundException e) {
             return Response.serverError().status(Response.Status.BAD_REQUEST).build();
         }
 
         log.debug("Creating pseudowires {} from rest api!", pseudowires);
         List<Pair<DefaultL2TunnelDescription, String>> failed = new ArrayList<>();
-
-        for (DefaultL2TunnelDescription pw : pseudowires) {
+        for (L2TunnelDescription pw : pseudowires.getRight()) {
             L2TunnelHandler.Result res = srService.addPseudowire(pw);
-            if (!(res == L2TunnelHandler.Result.SUCCESS)) {
-                log.trace("Could not create pseudowire {} : {}", pw.l2Tunnel().tunnelId(), res.getSpecificError());
-                failed.add(Pair.of(pw, res.getSpecificError()));
+            if (res != L2TunnelHandler.Result.SUCCESS) {
+                log.error("Could not create pseudowire {} : {}", pw.l2Tunnel().tunnelId(), res.getSpecificError());
+                failed.add(Pair.of((DefaultL2TunnelDescription) pw, res.getSpecificError()));
             }
         }
+        List<Pair<JsonNode, String>> undecodedPws = pseudowires.getLeft();
 
-        if (failed.size() == 0) {
-            // all pseudowires were instantiated
+        if ((failed.size() == 0) && (undecodedPws.size() == 0)) {
+            // all pseudowires were decoded and instantiated succesfully
             return Response.ok().build();
         } else {
             PseudowireCodec pwCodec = new PseudowireCodec();
             // some failed, need to report them to user
-            ObjectNode result = pwCodec.encodeFailedPseudowires(failed, this);
+            ObjectNode result = pwCodec.encodeFailedPseudowires(failed, undecodedPws, this);
             return Response.serverError().entity(result).build();
         }
     }
