diff --git a/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/BasicPceccHandler.java b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/BasicPceccHandler.java
new file mode 100644
index 0000000..3ed670d
--- /dev/null
+++ b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/BasicPceccHandler.java
@@ -0,0 +1,318 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.pce.pceservice;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.LinkedList;
+
+import org.onosproject.incubator.net.resource.label.DefaultLabelResource;
+import org.onosproject.incubator.net.resource.label.LabelResource;
+import org.onosproject.incubator.net.resource.label.LabelResourceId;
+import org.onosproject.incubator.net.resource.label.LabelResourceService;
+import org.onosproject.incubator.net.tunnel.Tunnel;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.pce.pcestore.api.PceStore;
+import org.onosproject.pce.pcestore.api.LspLocalLabelInfo;
+import org.onosproject.pce.pcestore.PceccTunnelInfo;
+import org.onosproject.pce.pcestore.DefaultLspLocalLabelInfo;
+import org.onosproject.net.Link;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Multimap;
+
+/**
+ * Basic PCECC handler.
+ * In Basic PCECC, after path computation will configure IN and OUT label to nodes.
+ * [X]OUT---link----IN[Y]OUT---link-----IN[Z] where X, Y and Z are nodes.
+ * For generating labels, will go thorough links in the path from Egress to Ingress.
+ * In each link, will take label from destination node local pool as IN label,
+ * and assign this label as OUT label to source node.
+ */
+public final class BasicPceccHandler {
+    private static final Logger log = LoggerFactory.getLogger(BasicPceccHandler.class);
+
+    private static final String LABEL_RESOURCE_SERVICE_NULL = "Label Resource Service cannot be null";
+    private static final String PCE_STORE_NULL = "PCE Store cannot be null";
+    private static BasicPceccHandler crHandlerInstance = null;
+    private LabelResourceService labelRsrcService;
+    private PceStore pceStore;
+
+    /**
+     * Initializes default values.
+     */
+    private BasicPceccHandler() {
+    }
+
+    /**
+     * Returns single instance of this class.
+     *
+     * @return this class single instance
+     */
+    public static BasicPceccHandler getInstance() {
+        if (crHandlerInstance == null) {
+            crHandlerInstance = new BasicPceccHandler();
+        }
+        return crHandlerInstance;
+    }
+
+    /**
+     * Initialization of label manager and pce store.
+     *
+     * @param labelRsrcService label resource service
+     * @param pceStore pce label store
+     */
+    public void initialize(LabelResourceService labelRsrcService, PceStore pceStore) {
+        this.labelRsrcService = labelRsrcService;
+        this.pceStore = pceStore;
+    }
+
+    /**
+     * Allocates labels from local resource pool and configure these (IN and OUT) labels into devices.
+     *
+     * @param tunnel tunnel between ingress to egress
+     * @return success or failure
+     */
+    public boolean allocateLabel(Tunnel tunnel) {
+        long applyNum = 1;
+        boolean isLastLabelToPush = false;
+        Collection<LabelResource> labelRscList;
+
+        checkNotNull(labelRsrcService, LABEL_RESOURCE_SERVICE_NULL);
+        checkNotNull(pceStore, PCE_STORE_NULL);
+
+        List<Link> linkList = tunnel.path().links();
+        if ((linkList != null) && (linkList.size() > 0)) {
+            // Sequence through reverse order to push local labels into devices
+            // Generation of labels from egress to ingress
+            for (ListIterator iterator = linkList.listIterator(linkList.size()); iterator.hasPrevious();) {
+                Link link = (Link) iterator.previous();
+                DeviceId dstDeviceId = link.dst().deviceId();
+                DeviceId srcDeviceId = link.src().deviceId();
+                labelRscList = labelRsrcService.applyFromDevicePool(dstDeviceId, applyNum);
+                if ((labelRscList != null) && (labelRscList.size() > 0)) {
+                    // Link label value is taken from destination device local pool.
+                    // [X]OUT---link----IN[Y]OUT---link-----IN[Z] where X, Y and Z are nodes.
+                    // Link label value is used as OUT and IN for both ends
+                    // (source and destination devices) of the link.
+                    // Currently only one label is allocated to a device (destination device).
+                    // So, no need to iterate through list
+                    Iterator<LabelResource> labelIterator = labelRscList.iterator();
+                    DefaultLabelResource defaultLabelResource = (DefaultLabelResource) labelIterator.next();
+                    LabelResourceId labelId = defaultLabelResource.labelResourceId();
+                    log.debug("Allocated local label: " + labelId.toString()
+                              + "to device: " + defaultLabelResource.deviceId().toString());
+                    PortNumber dstPort = link.dst().port();
+
+                    // Check whether this is last link label to push
+                    if (!iterator.hasPrevious()) {
+                       isLastLabelToPush = true;
+                    }
+
+                    // Push into destination device
+                    //TODO: uncomment below lines once installLocalLabelRule() method is ready
+                    // Destination device IN port is link.dst().port()
+                    //installLocalLabelRule(dstDeviceId, labelId, dstPort, tunnel.tunnelId(), isLastLabelToPush,
+                    //                      LabelType.IN, Objective.Operation.ADD);
+
+                    // Push into source device
+                    //TODO: uncomment below lines once installLocalLabelRule() method is ready
+                    // Source device OUT port will be link.dst().port(). Means its remote port used to send packet.
+                    //installLocalLabelRule(srcDeviceId, labelId, dstPort, tunnel.tunnelId(), isLastLabelToPush,
+                    //                      LabelType.OUT, Objective.Operation.ADD);
+
+                    // Add or update pcecc tunnel info in pce store.
+                    updatePceccTunnelInfoInStore(srcDeviceId, dstDeviceId, labelId, dstPort,
+                                                 tunnel, isLastLabelToPush);
+                } else {
+                    log.error("Unable to allocate label to device id {}.", dstDeviceId.toString());
+                    releaseLabel(tunnel);
+                    return false;
+                }
+            }
+        } else {
+           log.error("Tunnel {} is having empty links.", tunnel.toString());
+           return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Updates list of local labels of PCECC tunnel info in pce store.
+     *
+     * @param srcDeviceId source device in a link
+     * @param dstDeviceId destination device in a link
+     * @param labelId label id of a link
+     * @param dstPort destination device port number of a link
+     * @param tunnel tunnel
+     * @param isLastLabelToPush indicates this is the last label to push in Basic PCECC case
+     */
+    public void updatePceccTunnelInfoInStore(DeviceId srcDeviceId, DeviceId dstDeviceId, LabelResourceId labelId,
+                                                PortNumber dstPort, Tunnel tunnel, boolean isLastLabelToPush) {
+       // First try to retrieve device from store and update its label id if it is exists,
+       // otherwise add it
+       boolean dstDeviceUpdated = false;
+       boolean srcDeviceUpdated = false;
+
+       PceccTunnelInfo pceccTunnelInfo = pceStore.getTunnelInfo(tunnel.tunnelId());
+       List<LspLocalLabelInfo> lspLabelInfoList;
+       if (pceccTunnelInfo != null) {
+           lspLabelInfoList = pceccTunnelInfo.lspLocalLabelInfoList();
+           if ((lspLabelInfoList != null) && (lspLabelInfoList.size() > 0)) {
+               for (int i = 0; i < lspLabelInfoList.size(); ++i) {
+                   LspLocalLabelInfo lspLocalLabelInfo =
+                           (DefaultLspLocalLabelInfo) lspLabelInfoList.get(i);
+                   LspLocalLabelInfo.Builder lspLocalLabelInfoBuilder = null;
+                   if (dstDeviceId.equals(lspLocalLabelInfo.deviceId())) {
+                       lspLocalLabelInfoBuilder = DefaultLspLocalLabelInfo.builder(lspLocalLabelInfo);
+                       lspLocalLabelInfoBuilder.inLabelId(labelId);
+                       // Destination device IN port will be link destination port
+                       lspLocalLabelInfoBuilder.inPort(dstPort);
+                       dstDeviceUpdated = true;
+                   } else if (srcDeviceId.equals(lspLocalLabelInfo.deviceId())) {
+                       lspLocalLabelInfoBuilder = DefaultLspLocalLabelInfo.builder(lspLocalLabelInfo);
+                       lspLocalLabelInfoBuilder.outLabelId(labelId);
+                       // Source device OUT port will be link destination (remote) port
+                       lspLocalLabelInfoBuilder.outPort(dstPort);
+                       srcDeviceUpdated = true;
+                   }
+
+                   // Update
+                   if ((lspLocalLabelInfoBuilder != null) && (dstDeviceUpdated || srcDeviceUpdated)) {
+                       lspLabelInfoList.set(i, lspLocalLabelInfoBuilder.build());
+                   }
+               }
+           }
+       }
+
+       // If it is not found in store then add it to store
+       if (!dstDeviceUpdated || !srcDeviceUpdated) {
+           // If tunnel info itself not available then create new one, otherwise add node to list.
+           if (pceccTunnelInfo == null) {
+              pceccTunnelInfo = new PceccTunnelInfo();
+              lspLabelInfoList = new LinkedList<>();
+           } else {
+              lspLabelInfoList = pceccTunnelInfo.lspLocalLabelInfoList();
+              if (lspLabelInfoList == null) {
+                 lspLabelInfoList = new LinkedList<>();
+              }
+           }
+
+           if (!dstDeviceUpdated) {
+               LspLocalLabelInfo lspLocalLabelInfo = DefaultLspLocalLabelInfo.builder()
+                   .deviceId(dstDeviceId)
+                   .inLabelId(labelId)
+                   .outLabelId(null)
+                   .inPort(dstPort) // Destination device IN port will be link destination port
+                   .outPort(null)
+                   .build();
+               lspLabelInfoList.add(lspLocalLabelInfo);
+           }
+
+           if (!srcDeviceUpdated) {
+               LspLocalLabelInfo lspLocalLabelInfo = DefaultLspLocalLabelInfo.builder()
+                   .deviceId(srcDeviceId)
+                   .inLabelId(null)
+                   .outLabelId(labelId)
+                   .inPort(null)
+                   .outPort(dstPort) // Source device OUT port will be link destination (remote) port
+                   .build();
+               lspLabelInfoList.add(lspLocalLabelInfo);
+           }
+
+           pceccTunnelInfo.lspLocalLabelInfoList(lspLabelInfoList);
+           pceStore.addTunnelInfo(tunnel.tunnelId(), pceccTunnelInfo);
+       }
+    }
+
+    /**
+     * Deallocates unused labels to device pools.
+     *
+     * @param tunnel tunnel between ingress to egress
+     */
+    public void releaseLabel(Tunnel tunnel) {
+       boolean isLastLabelToPush = false;
+
+       checkNotNull(labelRsrcService, LABEL_RESOURCE_SERVICE_NULL);
+       checkNotNull(pceStore, PCE_STORE_NULL);
+
+       Multimap<DeviceId, LabelResource> release = ArrayListMultimap.create();
+       PceccTunnelInfo pceccTunnelInfo = pceStore.getTunnelInfo(tunnel.tunnelId());
+       if (pceccTunnelInfo != null) {
+           List<LspLocalLabelInfo> lspLocalLabelInfoList = pceccTunnelInfo.lspLocalLabelInfoList();
+           if ((lspLocalLabelInfoList != null) && (lspLocalLabelInfoList.size() > 0)) {
+               for (Iterator<LspLocalLabelInfo> iterator = lspLocalLabelInfoList.iterator(); iterator.hasNext();) {
+                   LspLocalLabelInfo lspLocalLabelInfo = (DefaultLspLocalLabelInfo) iterator.next();
+                   DeviceId deviceId = lspLocalLabelInfo.deviceId();
+                   LabelResourceId inLabelId = lspLocalLabelInfo.inLabelId();
+                   LabelResourceId outLabelId = lspLocalLabelInfo.outLabelId();
+                   PortNumber inPort = lspLocalLabelInfo.inPort();
+                   PortNumber outPort = lspLocalLabelInfo.outPort();
+
+                   // Check whether this is last link label to push
+                   if (!iterator.hasNext()) {
+                      isLastLabelToPush = true;
+                   }
+
+                   // Push into device
+                   if ((inLabelId != null) && (inPort != null)) {
+                       //TODO: uncomment below lines once installLocalLabelRule() method is ready
+                       //installLocalLabelRule(deviceId, inLabelId, inPort, tunnelId, isLastLabelToPush,
+                       //                      LabelType.IN, Objective.Operation.REMOVE);
+                   }
+
+                   if ((outLabelId != null) && (outPort != null)) {
+                       //TODO: uncomment below lines once installLocalLabelRule() method is ready
+                       //installLocalLabelRule(deviceId, outLabelId, outPort, tunnelId, isLastLabelToPush,
+                       //                      LabelType.OUT, Objective.Operation.REMOVE);
+                   }
+
+                   // List is stored from egress to ingress. So, using IN label id to release.
+                   // Only one local label is assigned to device (destination node)
+                   // and that is used as OUT label for source node.
+                   // No need to release label for last node in the list from pool because label was not allocated to
+                   // ingress node (source node).
+                   if ((iterator.hasNext()) && (inLabelId != null)) {
+                       LabelResource labelRsc = new DefaultLabelResource(deviceId, inLabelId);
+                       release.put(deviceId, labelRsc);
+                   }
+               }
+           }
+
+           // Release from label pool
+           if (!release.isEmpty()) {
+              labelRsrcService.releaseToDevicePool(release);
+           }
+
+           // Remove tunnel info only if tunnel consumer id is not saved.
+           // If tunnel consumer id is saved, this tunnel info will be removed during releasing bandwidth.
+           if (pceccTunnelInfo.tunnelConsumerId() == null) {
+               pceStore.removeTunnelInfo(tunnel.tunnelId());
+           }
+       } else {
+           log.error("Unable to find PCECC tunnel info in store for a tunnel {}.", tunnel.toString());
+       }
+   }
+}
diff --git a/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/LabelType.java b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/LabelType.java
new file mode 100644
index 0000000..78e57f0
--- /dev/null
+++ b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/LabelType.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.pce.pceservice;
+
+/**
+ * Describes about Label type.
+ */
+public enum LabelType {
+    /**
+     * Signifies in label id of a device.
+     */
+    OUT_LABEL(0),
+
+    /**
+     * Signifies out label id of a device.
+     */
+    IN_LABEL(1);
+
+    int value;
+
+    /**
+     * Assign val with the value as the Label type.
+     *
+     * @param val Label type
+     */
+    LabelType(int val) {
+        value = val;
+    }
+
+    /**
+     * Returns value of Label type.
+     *
+     * @return label type
+     */
+    public byte type() {
+        return (byte) value;
+    }
+}
diff --git a/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/PceccSrTeBeHandler.java b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/PceccSrTeBeHandler.java
new file mode 100644
index 0000000..2a10dcf
--- /dev/null
+++ b/apps/pce/app/src/main/java/org/onosproject/pce/pceservice/PceccSrTeBeHandler.java
@@ -0,0 +1,389 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.pce.pceservice;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Set;
+
+import org.onosproject.incubator.net.resource.label.DefaultLabelResource;
+import org.onosproject.incubator.net.resource.label.LabelResource;
+import org.onosproject.incubator.net.resource.label.LabelResourceId;
+import org.onosproject.incubator.net.resource.label.LabelResourceAdminService;
+import org.onosproject.incubator.net.resource.label.LabelResourceService;
+import org.onosproject.incubator.net.tunnel.DefaultLabelStack;
+import org.onosproject.incubator.net.tunnel.LabelStack;
+import org.onosproject.net.DeviceId;
+import org.onosproject.pce.pcestore.api.PceStore;
+import org.onosproject.net.Link;
+import org.onosproject.net.Path;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Multimap;
+
+/**
+ * PCE SR-BE and SR-TE functionality.
+ * SR-BE: Each node (PCC) is allocated a node-SID (label) by the PCECC. The PCECC sends PCLabelUpd to
+ * update the label map of each node to all the nodes in the domain.
+ * SR-TE: apart from node-SID, Adj-SID is used where each adjacency is allocated an Adj-SID (label) by the PCECC.
+ * The PCECC sends PCLabelUpd to update the label map of each Adj to the corresponding nodes in the domain.
+ */
+public final class PceccSrTeBeHandler {
+    private static final Logger log = LoggerFactory.getLogger(PceccSrTeBeHandler.class);
+
+    private static final String LABEL_RESOURCE_ADMIN_SERVICE_NULL = "Label Resource Admin Service cannot be null";
+    private static final String LABEL_RESOURCE_SERVICE_NULL = "Label Resource Service cannot be null";
+    private static final String PCE_STORE_NULL = "PCE Store cannot be null";
+    private static final String DEVICE_SERVICE_NULL = "Device Service cannot be null";
+    private static final String DEVICE_ID_NULL = "Device-Id cannot be null";
+    private static final String LSR_ID_NULL = "LSR-Id cannot be null";
+    private static final String DEVICE_ID_LSR_ID_MAP_NULL = "Device-Id and LSR-Id map cannot be null";
+    private static final String LINK_NULL = "Link cannot be null";
+    private static final String PATH_NULL = "Path cannot be null";
+    private static final String LSR_ID = "lsrId";
+    private static final int PREFIX_LENGTH = 32;
+    private static PceccSrTeBeHandler srTeHandlerInstance = null;
+    private LabelResourceAdminService labelRsrcAdminService;
+    private LabelResourceService labelRsrcService;
+    private PceStore pceStore;
+
+    /**
+     * Initializes default values.
+     */
+    private PceccSrTeBeHandler() {
+    }
+
+    /**
+     * Returns single instance of this class.
+     *
+     * @return this class single instance
+     */
+    public static PceccSrTeBeHandler getInstance() {
+        if (srTeHandlerInstance == null) {
+            srTeHandlerInstance = new PceccSrTeBeHandler();
+        }
+        return srTeHandlerInstance;
+    }
+
+    /**
+     * Initialization of label manager interfaces and pce store.
+     *
+     * @param labelRsrcAdminService label resource admin service
+     * @param labelRsrcService label resource service
+     * @param pceStore PCE label store
+     */
+    public void initialize(LabelResourceAdminService labelRsrcAdminService,
+                           LabelResourceService labelRsrcService, PceStore pceStore) {
+        this.labelRsrcAdminService = labelRsrcAdminService;
+        this.labelRsrcService = labelRsrcService;
+        this.pceStore = pceStore;
+    }
+
+    /**
+     * Reserves the global label pool.
+     *
+     * @param beginLabel minimum value of global label space
+     * @param endLabel maximum value of global label space
+     * @return success or failure
+     */
+    public boolean reserveGlobalPool(long beginLabel, long endLabel) {
+        checkNotNull(labelRsrcAdminService, LABEL_RESOURCE_ADMIN_SERVICE_NULL);
+        return labelRsrcAdminService.createGlobalPool(LabelResourceId.labelResourceId(beginLabel),
+                                                      LabelResourceId.labelResourceId(endLabel));
+    }
+
+    /**
+     * Allocates node label from global node label pool to specific device.
+     * Configure this device with labels and lsrid mapping of all other devices and vice versa.
+     *
+     * @param specificDeviceId node label needs to be allocated to specific device
+     * @param specificLsrId lsrid of specific device
+     * @param deviceIdLsrIdMap deviceid and lsrid mapping
+     * @return success or failure
+     */
+    public boolean allocateNodeLabel(DeviceId specificDeviceId, String specificLsrId,
+                                     Map<DeviceId, String> deviceIdLsrIdMap) {
+        long applyNum = 1; // For each node only one node label
+        LabelResourceId specificLabelId = null;
+
+        checkNotNull(specificDeviceId, DEVICE_ID_NULL);
+        checkNotNull(specificLsrId, LSR_ID_NULL);
+        checkNotNull(deviceIdLsrIdMap, DEVICE_ID_LSR_ID_MAP_NULL);
+        checkNotNull(labelRsrcService, LABEL_RESOURCE_SERVICE_NULL);
+        checkNotNull(pceStore, PCE_STORE_NULL);
+
+        // The specificDeviceId is the new device and is not there in the deviceIdLsrIdMap.
+        // So, first generate its label and configure label and its lsr-id to it.
+        Collection<LabelResource> result = labelRsrcService.applyFromGlobalPool(applyNum);
+        if (result.size() > 0) {
+           // Only one element (label-id) to retrieve
+           Iterator<LabelResource> iterator = result.iterator();
+           DefaultLabelResource defaultLabelResource = (DefaultLabelResource) iterator.next();
+           specificLabelId = defaultLabelResource.labelResourceId();
+           if (specificLabelId == null) {
+              log.error("Unable to retrieve global node label for a device id {}.", specificDeviceId.toString());
+              return false;
+           }
+        } else {
+           log.error("Unable to allocate global node label for a device id {}.", specificDeviceId.toString());
+           return false;
+        }
+
+        pceStore.addGlobalNodeLabel(specificDeviceId, specificLabelId);
+        //TODO: uncomment below line once advertiseNodeLabelRule() is ready
+        // Push its label information into specificDeviceId
+        //advertiseNodeLabelRule(specificDeviceId, specificLabelId,
+        //                       IpPrefix.valueOf(IpAddress.valueOf(specificLsrId), PREFIX_LENGTH),
+
+        // Configure (node-label, lsr-id) mapping of each devices in list to specific device and vice versa.
+        for (Map.Entry element:deviceIdLsrIdMap.entrySet()) {
+           DeviceId otherDevId = (DeviceId) element.getKey();
+           String otherLsrId = (String) element.getValue();
+           if (otherLsrId == null) {
+               log.error("The lsr-id of device id {} is null.", otherDevId.toString());
+               releaseNodeLabel(specificDeviceId, specificLsrId, deviceIdLsrIdMap);
+               return false;
+           }
+
+           // Label for other device in list should be already allocated.
+           LabelResourceId otherLabelId = pceStore.getGlobalNodeLabel(otherDevId);
+           if (otherLabelId == null) {
+              log.error("Unable to find global node label in store for a device id {}.", otherDevId.toString());
+              releaseNodeLabel(specificDeviceId, specificLsrId, deviceIdLsrIdMap);
+              return false;
+           }
+
+           // Push to device
+           // TODO: uncomment below line once advertiseNodeLabelRule() is ready
+           // Push label information of specificDeviceId to otherDevId in list and vice versa.
+           //advertiseNodeLabelRule(otherDevId, specificLabelId, IpPrefix.valueOf(IpAddress.valueOf(specificLsrId),
+           //                       PREFIX_LENGTH), Objective.Operation.ADD);
+           //advertiseNodeLabelRule(specificDeviceId, otherLabelId, IpPrefix.valueOf(IpAddress.valueOf(otherLsrId),
+           //                       PREFIX_LENGTH), Objective.Operation.ADD);
+        }
+
+        return true;
+    }
+
+    /**
+     * Releases assigned node label of specific device from global node label pool and pce store.
+     * and remove configured this node label from all other devices.
+     *
+     * @param specificDeviceId node label needs to be released for specific device
+     * @param specificLsrId lsrid of specific device
+     * @param deviceIdLsrIdMap deviceid and lsrid mapping
+     * @return success or failure
+     */
+    public boolean releaseNodeLabel(DeviceId specificDeviceId, String specificLsrId,
+                                    Map<DeviceId, String> deviceIdLsrIdMap) {
+        checkNotNull(specificDeviceId, DEVICE_ID_NULL);
+        checkNotNull(specificLsrId, LSR_ID_NULL);
+        checkNotNull(deviceIdLsrIdMap, DEVICE_ID_LSR_ID_MAP_NULL);
+        checkNotNull(labelRsrcService, LABEL_RESOURCE_SERVICE_NULL);
+        checkNotNull(pceStore, PCE_STORE_NULL);
+        boolean retValue = true;
+
+        // Release node label entry of this specific device from all other devices
+        // Retrieve node label of this specific device from store
+        LabelResourceId labelId = pceStore.getGlobalNodeLabel(specificDeviceId);
+        if (labelId == null) {
+           log.error("Unable to retrieve label of a device id {} from store.", specificDeviceId.toString());
+           return false;
+        }
+
+        // Go through all devices in the map and remove label entry
+        for (Map.Entry element:deviceIdLsrIdMap.entrySet()) {
+           DeviceId otherDevId = (DeviceId) element.getKey();
+
+           // Remove this specific device label information from all other nodes except
+           // this specific node where connection already lost.
+           if (!specificDeviceId.equals(otherDevId)) {
+              //TODO: uncomment below lines once advertiseNodeLabelRule() is ready
+              //advertiseNodeLabelRule(otherDevId, labelId, IpPrefix.valueOf(IpAddress.valueOf(specificLsrId),
+              //                       PREFIX_LENGTH), Objective.Operation.REMOVE);
+           }
+        }
+
+        // Release from label manager
+        Set<LabelResourceId> release = new HashSet<>();
+        release.add(labelId);
+        if (!labelRsrcService.releaseToGlobalPool(release)) {
+            log.error("Unable to release label id {} from label manager.", labelId.toString());
+            retValue = false;
+        }
+
+        // Remove from store
+        if (!pceStore.removeGlobalNodeLabel(specificDeviceId)) {
+            log.error("Unable to remove global node label id {} from store.", labelId.toString());
+            retValue = false;
+        }
+
+        return retValue;
+    }
+
+    /**
+     * Allocates adjacency label to a link from local resource pool by a specific device id.
+     *
+     * @param link between devices
+     * @return success or failure
+     */
+    public boolean allocateAdjacencyLabel(Link link) {
+        long applyNum = 1; // Single label to each link.
+        DeviceId srcDeviceId = link.src().deviceId();
+        Collection<LabelResource> labelList;
+
+        checkNotNull(link, LINK_NULL);
+        checkNotNull(labelRsrcService, LABEL_RESOURCE_SERVICE_NULL);
+        checkNotNull(pceStore, PCE_STORE_NULL);
+
+        // Allocate adjacency label to a link from label manager.
+        // Take label from source device pool to allocate.
+        labelList = labelRsrcService.applyFromDevicePool(srcDeviceId, applyNum);
+        if (labelList.size() <= 0) {
+           log.error("Unable to allocate label to a device id {}.", srcDeviceId.toString());
+           return false;
+        }
+
+        // Currently only one label to a device. So, no need to iterate through list
+        Iterator<LabelResource> iterator = labelList.iterator();
+        DefaultLabelResource defaultLabelResource = (DefaultLabelResource) iterator.next();
+        LabelResourceId labelId = defaultLabelResource.labelResourceId();
+        if (labelId == null) {
+           log.error("Unable to allocate label to a device id {}.", srcDeviceId.toString());
+           return false;
+        }
+        log.debug("Allocated adjacency label {} to a link {}.", labelId.toString(),
+                  link.toString());
+
+        // Push adjacency label to device
+        //TODO: uncomment below line once installAdjLabelRule() method is ready
+        //installAdjLabelRule(srcDeviceId, labelId, link.src().port(), link.dst().port(), Objective.Operation.ADD);
+
+        // Save in store
+        pceStore.addAdjLabel(link, labelId);
+        return true;
+    }
+
+   /**
+     * Releases unused adjacency labels from device pools.
+     *
+     * @param link between devices
+     * @return success or failure
+     */
+    public boolean releaseAdjacencyLabel(Link link) {
+       checkNotNull(link, LINK_NULL);
+       checkNotNull(labelRsrcService, LABEL_RESOURCE_SERVICE_NULL);
+       checkNotNull(pceStore, PCE_STORE_NULL);
+       boolean retValue = true;
+
+       // Retrieve link label from store
+       LabelResourceId labelId = pceStore.getAdjLabel(link);
+       if (labelId == null) {
+          log.error("Unabel to retrieve label for a link {} from store.", link.toString());
+          return false;
+       }
+
+       // Device
+       DeviceId srcDeviceId = link.src().deviceId();
+
+       // Release adjacency label from device
+       //TODO: uncomment below line once installAdjLabelRule() method is ready
+       //installAdjLabelRule(srcDeviceId, labelId, link.src().port(), link.dst().port(), Objective.Operation.REMOVE);
+
+       // Release link label from label manager
+       Multimap<DeviceId, LabelResource> release = ArrayListMultimap.create();
+       DefaultLabelResource defaultLabelResource = new DefaultLabelResource(srcDeviceId, labelId);
+       release.put(srcDeviceId, defaultLabelResource);
+       if (!labelRsrcService.releaseToDevicePool(release)) {
+          log.error("Unable to release label id {} from label manager.", labelId.toString());
+          retValue = false;
+       }
+
+       // Remove adjacency label from store
+       if (!pceStore.removeAdjLabel(link)) {
+          log.error("Unable to remove adjacency label id {} from store.", labelId.toString());
+          retValue = false;
+       }
+       return retValue;
+    }
+
+    /**
+     * Computes label stack for a path.
+     *
+     * @param path lsp path
+     * @return label stack
+     */
+    public LabelStack computeLabelStack(Path path) {
+        checkNotNull(path, PATH_NULL);
+        // Label stack is linked list to make labels in order.
+        List<LabelResourceId> labelStack = new LinkedList<>();
+        List<Link> linkList = path.links();
+        if ((linkList != null) && (linkList.size() > 0)) {
+            // Path: [x] ---- [y] ---- [z]
+            // For other than last link, add only source[x] device label.
+            // For the last link, add both source[y] and destination[z] device labels.
+            // For all links add adjacency label
+            Link link = null;
+            LabelResourceId nodeLabelId = null;
+            LabelResourceId adjLabelId = null;
+            DeviceId deviceId = null;
+            for (Iterator<Link> iterator = linkList.iterator(); iterator.hasNext();) {
+                link = (Link) iterator.next();
+                // Add source device label now
+                deviceId = link.src().deviceId();
+                nodeLabelId = pceStore.getGlobalNodeLabel(deviceId);
+                if (nodeLabelId == null) {
+                   log.error("Unable to find node label for a device id {} in store.", deviceId.toString());
+                   return null;
+                }
+                labelStack.add(nodeLabelId);
+
+                // Add adjacency label for this link
+                adjLabelId = pceStore.getAdjLabel(link);
+                if (adjLabelId == null) {
+                   log.error("Adjacency label id is null for a link {}.", link.toString());
+                   return null;
+                }
+                labelStack.add(adjLabelId);
+            }
+
+            // This is the last link in path
+            // Add destination device label now.
+            if (link != null) {
+               deviceId = link.dst().deviceId();
+               nodeLabelId = pceStore.getGlobalNodeLabel(deviceId);
+               if (nodeLabelId == null) {
+                  log.error("Unable to find node label for a device id {} in store.", deviceId.toString());
+                  return null;
+               }
+               labelStack.add(nodeLabelId);
+            }
+        } else {
+            log.debug("Empty link in path.");
+            return null;
+        }
+        return new DefaultLabelStack(labelStack);
+    }
+}
diff --git a/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/BasicPceccHandlerTest.java b/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/BasicPceccHandlerTest.java
new file mode 100644
index 0000000..a5ea175
--- /dev/null
+++ b/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/BasicPceccHandlerTest.java
@@ -0,0 +1,280 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.pce.pceservice;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.hamcrest.Matchers.nullValue;
+
+import static org.onosproject.net.Link.Type.DIRECT;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.LinkedList;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import org.onlab.packet.IpAddress;
+import org.onosproject.core.DefaultGroupId;
+import org.onosproject.incubator.net.tunnel.Tunnel;
+import org.onosproject.incubator.net.tunnel.TunnelEndPoint;
+import org.onosproject.incubator.net.tunnel.IpTunnelEndPoint;
+import org.onosproject.incubator.net.tunnel.TunnelName;
+import org.onosproject.incubator.net.tunnel.TunnelId;
+import org.onosproject.incubator.net.tunnel.DefaultTunnel;
+import org.onosproject.incubator.net.resource.label.LabelResourceId;
+import org.onosproject.incubator.net.resource.label.LabelResourceService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultPath;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.Path;
+import org.onosproject.pce.pcestore.api.LspLocalLabelInfo;
+import org.onosproject.pce.pcestore.api.PceStore;
+import org.onosproject.pce.pcestore.PceccTunnelInfo;
+import org.onosproject.pce.pcestore.DefaultLspLocalLabelInfo;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.pce.util.LabelResourceAdapter;
+import org.onosproject.pce.util.PceStoreAdapter;
+import org.onosproject.net.DefaultLink;
+import org.onosproject.net.Link;
+
+/**
+ * Unit tests for BasicPceccHandler class.
+ */
+public class BasicPceccHandlerTest {
+
+    public static final long LOCAL_LABEL_SPACE_MIN = 5122;
+    public static final long LOCAL_LABEL_SPACE_MAX = 9217;
+
+    private BasicPceccHandler pceccHandler;
+    protected LabelResourceService labelRsrcService;
+    protected PceStore pceStore;
+    private TunnelEndPoint src = IpTunnelEndPoint.ipTunnelPoint(IpAddress.valueOf(23423));
+    private TunnelEndPoint dst = IpTunnelEndPoint.ipTunnelPoint(IpAddress.valueOf(32421));
+    private DefaultGroupId groupId = new DefaultGroupId(92034);
+    private TunnelName tunnelName = TunnelName.tunnelName("TunnelName");
+    private TunnelId tunnelId = TunnelId.valueOf("41654654");
+    private ProviderId producerName = new ProviderId("producer1", "13");
+    private Path path;
+    private Tunnel tunnel;
+    private PceccTunnelInfo pceccTunnelInfo;
+    private DeviceId deviceId1;
+    private DeviceId deviceId2;
+    private DeviceId deviceId3;
+    private DeviceId deviceId4;
+    private DeviceId deviceId5;
+    private PortNumber port1;
+    private PortNumber port2;
+    private PortNumber port3;
+    private PortNumber port4;
+    private PortNumber port5;
+
+    @Before
+    public void setUp() throws Exception {
+       pceccHandler = BasicPceccHandler.getInstance();
+       labelRsrcService = new LabelResourceAdapter();
+       pceStore = new PceStoreAdapter();
+       pceccHandler.initialize(labelRsrcService, pceStore);
+
+       // Cretae tunnel test
+       // Link
+       ProviderId providerId = new ProviderId("of", "foo");
+       deviceId1 = DeviceId.deviceId("of:A");
+       deviceId2 = DeviceId.deviceId("of:B");
+       deviceId3 = DeviceId.deviceId("of:C");
+       deviceId4 = DeviceId.deviceId("of:D");
+       deviceId5 = DeviceId.deviceId("of:E");
+       port1 = PortNumber.portNumber(1);
+       port2 = PortNumber.portNumber(2);
+       port3 = PortNumber.portNumber(3);
+       port4 = PortNumber.portNumber(4);
+       port5 = PortNumber.portNumber(5);
+       List<Link> linkList = new LinkedList<>();
+
+       Link l1 = DefaultLink.builder()
+                            .providerId(providerId)
+                            .annotations(DefaultAnnotations.builder().set("key1", "yahoo").build())
+                            .src(new ConnectPoint(deviceId1, port1))
+                            .dst(new ConnectPoint(deviceId2, port2))
+                            .type(DIRECT)
+                            .state(Link.State.ACTIVE)
+                            .build();
+       linkList.add(l1);
+       Link l2 = DefaultLink.builder()
+                            .providerId(providerId)
+                            .annotations(DefaultAnnotations.builder().set("key2", "yahoo").build())
+                            .src(new ConnectPoint(deviceId2, port2))
+                            .dst(new ConnectPoint(deviceId3, port3))
+                            .type(DIRECT)
+                            .state(Link.State.ACTIVE)
+                            .build();
+       linkList.add(l2);
+       Link l3 = DefaultLink.builder()
+                            .providerId(providerId)
+                            .annotations(DefaultAnnotations.builder().set("key3", "yahoo").build())
+                            .src(new ConnectPoint(deviceId3, port3))
+                            .dst(new ConnectPoint(deviceId4, port4))
+                            .type(DIRECT)
+                            .state(Link.State.ACTIVE)
+                            .build();
+       linkList.add(l3);
+       Link l4 = DefaultLink.builder()
+                            .providerId(providerId)
+                            .annotations(DefaultAnnotations.builder().set("key4", "yahoo").build())
+                            .src(new ConnectPoint(deviceId4, port4))
+                            .dst(new ConnectPoint(deviceId5, port5))
+                            .type(DIRECT)
+                            .state(Link.State.ACTIVE)
+                            .build();
+       linkList.add(l4);
+
+       // Path
+       path = new DefaultPath(providerId, linkList, 10);
+
+       // Tunnel
+       tunnel = new DefaultTunnel(producerName, src, dst, Tunnel.Type.VXLAN,
+                                  Tunnel.State.ACTIVE, groupId, tunnelId,
+                                  tunnelName, path);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+    }
+
+    /**
+     * Checks the operation of getInstance() method.
+     */
+    @Test
+    public void testGetInstance() {
+        assertThat(pceccHandler, is(notNullValue()));
+    }
+
+    /**
+     * Checks the operation of allocateLabel() method.
+     */
+    @Test
+    public void testAllocateLabel() {
+       List<LspLocalLabelInfo> lspLocalLabelInfoList;
+       Iterator<LspLocalLabelInfo> iterator;
+       LspLocalLabelInfo lspLocalLabelInfo;
+       DeviceId deviceId;
+       LabelResourceId inLabelId;
+       LabelResourceId outLabelId;
+       PortNumber inPort;
+       PortNumber outPort;
+
+       // check allocation result
+       assertThat(pceccHandler.allocateLabel(tunnel), is(true));
+
+       // Check list of devices with IN and OUT labels whether stored properly in store
+       pceccTunnelInfo = pceStore.getTunnelInfo(tunnel.tunnelId());
+       lspLocalLabelInfoList = pceccTunnelInfo.lspLocalLabelInfoList();
+       iterator = lspLocalLabelInfoList.iterator();
+
+       // Retrieve values and check device5
+       lspLocalLabelInfo = (DefaultLspLocalLabelInfo) iterator.next();
+       deviceId = lspLocalLabelInfo.deviceId();
+       inLabelId = lspLocalLabelInfo.inLabelId();
+       outLabelId = lspLocalLabelInfo.outLabelId();
+       inPort = lspLocalLabelInfo.inPort();
+       outPort = lspLocalLabelInfo.outPort();
+
+       assertThat(deviceId, is(deviceId5));
+       assertThat(inLabelId, is(notNullValue()));
+       assertThat(outLabelId, is(nullValue()));
+       assertThat(inPort, is(port5));
+       assertThat(outPort, is(nullValue()));
+
+       // Next element check
+       // Retrieve values and check device4
+       lspLocalLabelInfo = (DefaultLspLocalLabelInfo) iterator.next();
+       deviceId = lspLocalLabelInfo.deviceId();
+       inLabelId = lspLocalLabelInfo.inLabelId();
+       outLabelId = lspLocalLabelInfo.outLabelId();
+       inPort = lspLocalLabelInfo.inPort();
+       outPort = lspLocalLabelInfo.outPort();
+
+       assertThat(deviceId, is(deviceId4));
+       assertThat(inLabelId, is(notNullValue()));
+       assertThat(outLabelId, is(notNullValue()));
+       assertThat(inPort, is(port4));
+       assertThat(outPort, is(port5));
+
+       // Next element check
+       // Retrieve values and check device3
+       lspLocalLabelInfo = (DefaultLspLocalLabelInfo) iterator.next();
+       deviceId = lspLocalLabelInfo.deviceId();
+       inLabelId = lspLocalLabelInfo.inLabelId();
+       outLabelId = lspLocalLabelInfo.outLabelId();
+       inPort = lspLocalLabelInfo.inPort();
+       outPort = lspLocalLabelInfo.outPort();
+
+       assertThat(deviceId, is(deviceId3));
+       assertThat(inLabelId, is(notNullValue()));
+       assertThat(outLabelId, is(notNullValue()));
+       assertThat(inPort, is(port3));
+       assertThat(outPort, is(port4));
+
+       // Next element check
+       // Retrieve values and check device2
+       lspLocalLabelInfo = (DefaultLspLocalLabelInfo) iterator.next();
+       deviceId = lspLocalLabelInfo.deviceId();
+       inLabelId = lspLocalLabelInfo.inLabelId();
+       outLabelId = lspLocalLabelInfo.outLabelId();
+       inPort = lspLocalLabelInfo.inPort();
+       outPort = lspLocalLabelInfo.outPort();
+
+       assertThat(deviceId, is(deviceId2));
+       assertThat(inLabelId, is(notNullValue()));
+       assertThat(outLabelId, is(notNullValue()));
+       assertThat(inPort, is(port2));
+       assertThat(outPort, is(port3));
+
+       // Next element check
+       // Retrieve values and check device1
+       lspLocalLabelInfo = (DefaultLspLocalLabelInfo) iterator.next();
+       deviceId = lspLocalLabelInfo.deviceId();
+       inLabelId = lspLocalLabelInfo.inLabelId();
+       outLabelId = lspLocalLabelInfo.outLabelId();
+       inPort = lspLocalLabelInfo.inPort();
+       outPort = lspLocalLabelInfo.outPort();
+
+       assertThat(deviceId, is(deviceId1));
+       assertThat(inLabelId, is(nullValue()));
+       assertThat(outLabelId, is(notNullValue()));
+       assertThat(inPort, is(nullValue()));
+       assertThat(outPort, is(port2));
+    }
+
+    /**
+     * Checks the operation of releaseLabel() method.
+     */
+    @Test
+    public void testReleaseLabel() {
+       // Release tunnels
+       assertThat(pceccHandler.allocateLabel(tunnel), is(true));
+       pceccHandler.releaseLabel(tunnel);
+
+       // Retrieve from store. Store should not contain this tunnel info.
+       pceccTunnelInfo = pceStore.getTunnelInfo(tunnel.tunnelId());
+       assertThat(pceccTunnelInfo, is(nullValue()));
+    }
+}
diff --git a/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/PceccSrTeBeHandlerTest.java b/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/PceccSrTeBeHandlerTest.java
new file mode 100644
index 0000000..93f7c69
--- /dev/null
+++ b/apps/pce/app/src/test/java/org/onosproject/pce/pceservice/PceccSrTeBeHandlerTest.java
@@ -0,0 +1,484 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.pce.pceservice;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.hamcrest.Matchers.nullValue;
+
+import static org.onosproject.net.Link.Type.DIRECT;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.List;
+import java.util.LinkedList;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import org.onosproject.incubator.net.resource.label.LabelResourceId;
+import org.onosproject.incubator.net.resource.label.LabelResourceAdminService;
+import org.onosproject.incubator.net.resource.label.LabelResourceService;
+import org.onosproject.incubator.net.tunnel.LabelStack;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultPath;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.Path;
+import org.onosproject.pce.pcestore.api.PceStore;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.pce.util.LabelResourceAdapter;
+import org.onosproject.pce.util.PceStoreAdapter;
+import org.onosproject.net.DefaultLink;
+import org.onosproject.net.Link;
+
+/**
+ * Unit tests for PceccSrTeBeHandler class.
+ */
+public class PceccSrTeBeHandlerTest {
+
+    public static final long GLOBAL_LABEL_SPACE_MIN = 4097;
+    public static final long GLOBAL_LABEL_SPACE_MAX = 5121;
+
+    private PceccSrTeBeHandler srTeHandler;
+    protected LabelResourceAdminService labelRsrcAdminService;
+    protected LabelResourceService labelRsrcService;
+    protected PceStore pceStore;
+    private ProviderId providerId;
+    private DeviceId deviceId1;
+    private DeviceId deviceId2;
+    private DeviceId deviceId3;
+    private DeviceId deviceId4;
+    private DeviceId deviceId5;
+    private PortNumber port1;
+    private PortNumber port2;
+    private PortNumber port3;
+    private PortNumber port4;
+    private PortNumber port5;
+    private Link link1;
+    private Link link2;
+    private Link link3;
+    private Link link4;
+    private Path path1;
+    LabelResourceId labelId;
+    private LabelResourceId labelId1 = LabelResourceId.labelResourceId(4098);
+    private LabelResourceId labelId2 = LabelResourceId.labelResourceId(4099);
+    private Map<DeviceId, String> deviceIdLsrIdMap;
+
+    @Before
+    public void setUp() throws Exception {
+        // Initialization of member variables
+        srTeHandler = PceccSrTeBeHandler.getInstance();
+        labelRsrcService = new LabelResourceAdapter();
+        labelRsrcAdminService = new LabelResourceAdapter();
+        pceStore = new PceStoreAdapter();
+        srTeHandler.initialize(labelRsrcAdminService, labelRsrcService, pceStore);
+
+        // Creates path
+        // Creates list of links
+        providerId = new ProviderId("of", "foo");
+        deviceId1 = DeviceId.deviceId("of:A");
+        deviceId2 = DeviceId.deviceId("of:B");
+        deviceId3 = DeviceId.deviceId("of:C");
+        deviceId4 = DeviceId.deviceId("of:D");
+        deviceId5 = DeviceId.deviceId("of:E");
+        port1 = PortNumber.portNumber(1);
+        port2 = PortNumber.portNumber(2);
+        port3 = PortNumber.portNumber(3);
+        port4 = PortNumber.portNumber(4);
+        port5 = PortNumber.portNumber(5);
+        List<Link> linkList = new LinkedList<>();
+
+        link1 = DefaultLink.builder()
+                .providerId(providerId)
+                .annotations(DefaultAnnotations.builder().set("key1", "yahoo").build())
+                .src(new ConnectPoint(deviceId1, port1))
+                .dst(new ConnectPoint(deviceId2, port2))
+                .type(DIRECT)
+                .state(Link.State.ACTIVE)
+                .build();
+        linkList.add(link1);
+        link2 = DefaultLink.builder()
+                .providerId(providerId)
+                .annotations(DefaultAnnotations.builder().set("key2", "yahoo").build())
+                .src(new ConnectPoint(deviceId2, port2))
+                .dst(new ConnectPoint(deviceId3, port3))
+                .type(DIRECT)
+                .state(Link.State.ACTIVE)
+                .build();
+        linkList.add(link2);
+        link3 = DefaultLink.builder()
+                .providerId(providerId)
+                .annotations(DefaultAnnotations.builder().set("key3", "yahoo").build())
+                .src(new ConnectPoint(deviceId3, port3))
+                .dst(new ConnectPoint(deviceId4, port4))
+                .type(DIRECT)
+                .state(Link.State.ACTIVE)
+                .build();
+        linkList.add(link3);
+        link4 = DefaultLink.builder()
+                .providerId(providerId)
+                .annotations(DefaultAnnotations.builder().set("key4", "yahoo").build())
+                .src(new ConnectPoint(deviceId4, port4))
+                .dst(new ConnectPoint(deviceId5, port5))
+                .type(DIRECT)
+                .state(Link.State.ACTIVE)
+                .build();
+        linkList.add(link4);
+
+        // Path
+        path1 = new DefaultPath(providerId, linkList, 10);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+    }
+
+    /**
+     * Checks the operation of getInstance() method.
+     */
+    @Test
+    public void testGetInstance() {
+        assertThat(srTeHandler, is(notNullValue()));
+    }
+
+    /**
+     * Checks the operation of reserveGlobalPool() method.
+     */
+    @Test
+    public void testReserveGlobalPool() {
+        assertThat(srTeHandler.reserveGlobalPool(GLOBAL_LABEL_SPACE_MIN,
+                GLOBAL_LABEL_SPACE_MAX), is(true));
+    }
+
+    /**
+     * Checks the operation of allocateNodeLabel() method on node label.
+     * Considered some nodes are already available before PceManager came up.
+     */
+    @Test
+    public void testAllocateNodeLabel1() {
+        // Specific device deviceId1
+
+        // Devices mapping with lsr-id
+        deviceIdLsrIdMap = new HashMap<>();
+
+        //device 1
+        String lsrId1 = "11.1.1.1";
+        deviceIdLsrIdMap.put(deviceId1, lsrId1);
+
+        // device 2
+        String lsrId2 = "12.1.1.1";
+        deviceIdLsrIdMap.put(deviceId2, lsrId2);
+
+        // device 3
+        String lsrId3 = "13.1.1.1";
+        deviceIdLsrIdMap.put(deviceId3, lsrId3);
+
+        // device 4
+        String lsrId4 = "14.1.1.1";
+        deviceIdLsrIdMap.put(deviceId4, lsrId4);
+
+        // device 5
+        String lsrId5 = "15.1.1.1";
+        deviceIdLsrIdMap.put(deviceId5, lsrId5);
+
+        // Considered devices are stored in deviceIdLsrIdMap.
+        // Creating temporary tempDeviceIdLsrIdMap to pass to allocateNodeLabel()
+        Map<DeviceId, String> tempDeviceIdLsrIdMap = new HashMap<>();
+        for (Map.Entry element : deviceIdLsrIdMap.entrySet()) {
+            DeviceId devId = (DeviceId) element.getKey();
+            String lsrId = (String) element.getValue();
+
+            // Allocate node label for specific device devId
+            assertThat(srTeHandler.allocateNodeLabel(devId, lsrId, tempDeviceIdLsrIdMap), is(true));
+
+            // Retrieve label from store
+            LabelResourceId labelId = pceStore.getGlobalNodeLabel(devId);
+
+            // Check whether label is generated for this device devId
+            assertThat(labelId, is(notNullValue()));
+
+            //Now add device to tempDeviceIdLsrIdMap
+            tempDeviceIdLsrIdMap.put(devId, lsrId);
+        }
+    }
+
+    /**
+     * Checks the operation of allocateNodeLabel() method on node label.
+     * Considered initially map is empty and keep on getting new devices from event.
+     */
+    @Test
+    public void testAllocateNodeLabel2() {
+        // Specific device deviceId1
+
+        // Device-id mapping with lsr-id
+        deviceIdLsrIdMap = new HashMap<>();
+
+        //device 1
+        String lsrId1 = "11.1.1.1";
+        // Allocate node label for specific device deviceId1
+        assertThat(srTeHandler.allocateNodeLabel(deviceId1, lsrId1, deviceIdLsrIdMap), is(true));
+        // Retrieve label from store
+        LabelResourceId labelId = pceStore.getGlobalNodeLabel(deviceId1);
+        // Check whether label is generated for this device deviceId1
+        assertThat(labelId, is(notNullValue()));
+        //Now add device to deviceIdLsrIdMap
+        deviceIdLsrIdMap.put(deviceId1, lsrId1);
+
+        // device 2
+        String lsrId2 = "12.1.1.1";
+        // Allocate node label for specific device deviceId2
+        assertThat(srTeHandler.allocateNodeLabel(deviceId2, lsrId2, deviceIdLsrIdMap), is(true));
+        // Retrieve label from store
+        labelId = pceStore.getGlobalNodeLabel(deviceId2);
+        // Check whether label is generated for this device deviceId2
+        assertThat(labelId, is(notNullValue()));
+        //Now add device to deviceIdLsrIdMap
+        deviceIdLsrIdMap.put(deviceId2, lsrId2);
+
+        // device 3
+        String lsrId3 = "13.1.1.1";
+        // Allocate node label for specific device deviceId3
+        assertThat(srTeHandler.allocateNodeLabel(deviceId3, lsrId3, deviceIdLsrIdMap), is(true));
+        // Retrieve label from store
+        labelId = pceStore.getGlobalNodeLabel(deviceId3);
+        // Check whether label is generated for this device deviceId3
+        assertThat(labelId, is(notNullValue()));
+        //Now add device to deviceIdLsrIdMap
+        deviceIdLsrIdMap.put(deviceId3, lsrId3);
+
+        // device 4
+        String lsrId4 = "14.1.1.1";
+        // Allocate node label for specific device deviceId4
+        assertThat(srTeHandler.allocateNodeLabel(deviceId4, lsrId4, deviceIdLsrIdMap), is(true));
+        // Retrieve label from store
+        labelId = pceStore.getGlobalNodeLabel(deviceId4);
+        // Check whether label is generated for this device deviceId4
+        assertThat(labelId, is(notNullValue()));
+        //Now add device to deviceIdLsrIdMap
+        deviceIdLsrIdMap.put(deviceId4, lsrId4);
+
+        // device 5
+        String lsrId5 = "15.1.1.1";
+        // Allocate node label for specific device deviceId5
+        assertThat(srTeHandler.allocateNodeLabel(deviceId5, lsrId5, deviceIdLsrIdMap), is(true));
+        // Retrieve label from store
+        labelId = pceStore.getGlobalNodeLabel(deviceId5);
+        // Check whether label is generated for this device deviceId5
+        assertThat(labelId, is(notNullValue()));
+        //Now add device to deviceIdLsrIdMap
+        deviceIdLsrIdMap.put(deviceId5, lsrId5);
+    }
+
+    /**
+     * Checks the operation of releaseNodeLabel() method on node label.
+     */
+    @Test
+    public void testReleaseNodeLabelSuccess() {
+        testAllocateNodeLabel2();
+        // Specific device deviceId1
+
+        //device 1
+        String lsrId1 = "11.1.1.1";
+        // Check whether successfully released node label
+        assertThat(srTeHandler.releaseNodeLabel(deviceId1, lsrId1, deviceIdLsrIdMap), is(true));
+        // Check whether successfully removed label from store
+        LabelResourceId labelId = pceStore.getGlobalNodeLabel(deviceId1);
+        assertThat(labelId, is(nullValue()));
+        // Remove released deviceId1
+        deviceIdLsrIdMap.remove(deviceId1);
+
+        //device 2
+        String lsrId2 = "12.1.1.1";
+        // Check whether successfully released node label
+        assertThat(srTeHandler.releaseNodeLabel(deviceId2, lsrId2, deviceIdLsrIdMap), is(true));
+        // Check whether successfully removed label from store
+        labelId = pceStore.getGlobalNodeLabel(deviceId2);
+        assertThat(labelId, is(nullValue()));
+        // Remove released deviceId2
+        deviceIdLsrIdMap.remove(deviceId2);
+
+        //device 3
+        String lsrId3 = "13.1.1.1";
+        // Check whether successfully released node label
+        assertThat(srTeHandler.releaseNodeLabel(deviceId3, lsrId3, deviceIdLsrIdMap), is(true));
+        // Check whether successfully removed label from store
+        labelId = pceStore.getGlobalNodeLabel(deviceId3);
+        assertThat(labelId, is(nullValue()));
+        // Remove released deviceId3
+        deviceIdLsrIdMap.remove(deviceId3);
+
+        //device 4
+        String lsrId4 = "14.1.1.1";
+        // Check whether successfully released node label
+        assertThat(srTeHandler.releaseNodeLabel(deviceId4, lsrId4, deviceIdLsrIdMap), is(true));
+        // Check whether successfully removed label from store
+        labelId = pceStore.getGlobalNodeLabel(deviceId4);
+        assertThat(labelId, is(nullValue()));
+        // Remove released deviceId4
+        deviceIdLsrIdMap.remove(deviceId4);
+
+        //device 5
+        String lsrId5 = "15.1.1.1";
+        // Check whether successfully released node label
+        assertThat(srTeHandler.releaseNodeLabel(deviceId5, lsrId5, deviceIdLsrIdMap), is(true));
+        // Check whether successfully removed label from store
+        labelId = pceStore.getGlobalNodeLabel(deviceId5);
+        assertThat(labelId, is(nullValue()));
+        // Remove released deviceId5
+        deviceIdLsrIdMap.remove(deviceId5);
+    }
+
+    @Test
+    public void testReleaseNodeLabelFailure() {
+        testAllocateNodeLabel2();
+
+        //device 6
+        String lsrId6 = "16.1.1.1";
+        // Check whether successfully released node label
+        DeviceId deviceId6 = DeviceId.deviceId("foo6");
+        assertThat(srTeHandler.releaseNodeLabel(deviceId6, lsrId6, deviceIdLsrIdMap), is(false));
+    }
+
+    /**
+     * Checks the operation of allocateAdjacencyLabel() method on adjacency label.
+     */
+    @Test
+    public void testAllocateAdjacencyLabel() {
+        // test link1
+        // Check whether adjacency label is allocated successfully.
+        assertThat(srTeHandler.allocateAdjacencyLabel(link1), is(true));
+        // Retrieve from store and check whether adjacency label is generated successfully for this device.
+        LabelResourceId labelId = pceStore.getAdjLabel(link1);
+        assertThat(labelId, is(notNullValue()));
+
+        // test link2
+        // Check whether adjacency label is allocated successfully.
+        assertThat(srTeHandler.allocateAdjacencyLabel(link2), is(true));
+        // Retrieve from store and check whether adjacency label is generated successfully for this device.
+        labelId = pceStore.getAdjLabel(link2);
+        assertThat(labelId, is(notNullValue()));
+
+        // test link3
+        // Check whether adjacency label is allocated successfully.
+        assertThat(srTeHandler.allocateAdjacencyLabel(link3), is(true));
+        // Retrieve from store and check whether adjacency label is generated successfully for this device.
+        labelId = pceStore.getAdjLabel(link3);
+        assertThat(labelId, is(notNullValue()));
+
+        // test link4
+        // Check whether adjacency label is allocated successfully.
+        assertThat(srTeHandler.allocateAdjacencyLabel(link4), is(true));
+        // Retrieve from store and check whether adjacency label is generated successfully for this device.
+        labelId = pceStore.getAdjLabel(link4);
+        assertThat(labelId, is(notNullValue()));
+    }
+
+    /**
+     * Checks the operation of releaseAdjacencyLabel() method on adjacency label.
+     */
+    @Test
+    public void testReleaseAdjacencyLabel() {
+        // Test link1
+        // Check whether adjacency label is released successfully.
+        assertThat(srTeHandler.allocateAdjacencyLabel(link1), is(true));
+        assertThat(srTeHandler.releaseAdjacencyLabel(link1), is(true));
+        // Retrieve from store and check whether adjacency label is removed successfully for this device.
+        LabelResourceId labelId = pceStore.getAdjLabel(link1);
+        assertThat(labelId, is(nullValue()));
+
+        // Test link2
+        // Check whether adjacency label is released successfully.
+        assertThat(srTeHandler.allocateAdjacencyLabel(link2), is(true));
+        assertThat(srTeHandler.releaseAdjacencyLabel(link2), is(true));
+        // Retrieve from store and check whether adjacency label is removed successfully for this device.
+        labelId = pceStore.getAdjLabel(link2);
+        assertThat(labelId, is(nullValue()));
+    }
+
+    /**
+     * Checks the operation of computeLabelStack() method.
+     */
+    @Test
+    public void testComputeLabelStack() {
+        // Allocate node labels to each devices
+        labelId = LabelResourceId.labelResourceId(4097);
+        pceStore.addGlobalNodeLabel(deviceId1, labelId);
+        labelId = LabelResourceId.labelResourceId(4098);
+        pceStore.addGlobalNodeLabel(deviceId2, labelId);
+        labelId = LabelResourceId.labelResourceId(4099);
+        pceStore.addGlobalNodeLabel(deviceId3, labelId);
+        labelId = LabelResourceId.labelResourceId(4100);
+        pceStore.addGlobalNodeLabel(deviceId4, labelId);
+        labelId = LabelResourceId.labelResourceId(4101);
+        pceStore.addGlobalNodeLabel(deviceId5, labelId);
+
+        // Allocate adjacency labels to each devices
+        labelId = LabelResourceId.labelResourceId(5122);
+        pceStore.addAdjLabel(link1, labelId);
+        labelId = LabelResourceId.labelResourceId(5123);
+        pceStore.addAdjLabel(link2, labelId);
+        labelId = LabelResourceId.labelResourceId(5124);
+        pceStore.addAdjLabel(link3, labelId);
+        labelId = LabelResourceId.labelResourceId(5125);
+        pceStore.addAdjLabel(link4, labelId);
+
+        // Compute label stack
+        LabelStack labelStack = srTeHandler.computeLabelStack(path1);
+
+        // check node-label of deviceId1
+        List<LabelResourceId> labelList = labelStack.labelResources();
+        Iterator<LabelResourceId> iterator = labelList.iterator();
+        labelId = (LabelResourceId) iterator.next();
+        assertThat(labelId, is(LabelResourceId.labelResourceId(4097)));
+
+        // check adjacency label of deviceId1
+        labelId = (LabelResourceId) iterator.next();
+        assertThat(labelId, is(LabelResourceId.labelResourceId(5122)));
+
+        // check node-label of deviceId2
+        labelId = (LabelResourceId) iterator.next();
+        assertThat(labelId, is(LabelResourceId.labelResourceId(4098)));
+
+        // check adjacency label of deviceId2
+        labelId = (LabelResourceId) iterator.next();
+        assertThat(labelId, is(LabelResourceId.labelResourceId(5123)));
+
+        // check node-label of deviceId3
+        labelId = (LabelResourceId) iterator.next();
+        assertThat(labelId, is(LabelResourceId.labelResourceId(4099)));
+
+        // check adjacency label of deviceId3
+        labelId = (LabelResourceId) iterator.next();
+        assertThat(labelId, is(LabelResourceId.labelResourceId(5124)));
+
+        // check node-label of deviceId4
+        labelId = (LabelResourceId) iterator.next();
+        assertThat(labelId, is(LabelResourceId.labelResourceId(4100)));
+
+        // check adjacency label of deviceId4
+        labelId = (LabelResourceId) iterator.next();
+        assertThat(labelId, is(LabelResourceId.labelResourceId(5125)));
+
+        // check node-label of deviceId5
+        labelId = (LabelResourceId) iterator.next();
+        assertThat(labelId, is(LabelResourceId.labelResourceId(4101)));
+    }
+}
diff --git a/apps/pce/app/src/test/java/org/onosproject/pce/util/LabelResourceAdapter.java b/apps/pce/app/src/test/java/org/onosproject/pce/util/LabelResourceAdapter.java
new file mode 100644
index 0000000..ca948b0
--- /dev/null
+++ b/apps/pce/app/src/test/java/org/onosproject/pce/util/LabelResourceAdapter.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.pce.util;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.Random;
+import java.util.Set;
+
+import org.onosproject.incubator.net.resource.label.DefaultLabelResource;
+import org.onosproject.incubator.net.resource.label.LabelResource;
+import org.onosproject.incubator.net.resource.label.LabelResourceAdminService;
+import org.onosproject.incubator.net.resource.label.LabelResourceDelegate;
+import org.onosproject.incubator.net.resource.label.LabelResourceEvent;
+import org.onosproject.incubator.net.resource.label.LabelResourceId;
+import org.onosproject.incubator.net.resource.label.LabelResourceListener;
+import org.onosproject.incubator.net.resource.label.LabelResourcePool;
+import org.onosproject.incubator.net.resource.label.LabelResourceProvider;
+import org.onosproject.incubator.net.resource.label.LabelResourceProviderRegistry;
+import org.onosproject.incubator.net.resource.label.LabelResourceProviderService;
+import org.onosproject.incubator.net.resource.label.LabelResourceService;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceEvent.Type;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.provider.AbstractListenerProviderRegistry;
+import org.onosproject.net.provider.AbstractProviderService;
+
+import com.google.common.collect.Multimap;
+
+/**
+ * Provides test implementation of class LabelResourceService.
+ */
+public class LabelResourceAdapter
+        extends AbstractListenerProviderRegistry<LabelResourceEvent, LabelResourceListener,
+                                                 LabelResourceProvider, LabelResourceProviderService>
+        implements LabelResourceService, LabelResourceAdminService, LabelResourceProviderRegistry {
+    public static final long GLOBAL_LABEL_SPACE_MIN = 4097;
+    public static final long GLOBAL_LABEL_SPACE_MAX = 5121;
+    public static final long LOCAL_LABEL_SPACE_MIN = 5122;
+    public static final long LOCAL_LABEL_SPACE_MAX = 9217;
+
+    private Random random = new Random();
+
+    @Override
+    public boolean createDevicePool(DeviceId deviceId,
+                                    LabelResourceId beginLabel,
+                                    LabelResourceId endLabel) {
+       return true;
+    }
+
+    @Override
+    public boolean createGlobalPool(LabelResourceId beginLabel,
+                                    LabelResourceId endLabel) {
+       return true;
+    }
+
+    @Override
+    public boolean destroyDevicePool(DeviceId deviceId) {
+       return true;
+    }
+
+    @Override
+    public boolean destroyGlobalPool() {
+       return true;
+    }
+
+    public long getLabelId(long min, long max) {
+      return random.nextInt((int) max - (int) min + 1) + (int) min;
+    }
+
+    public Collection<LabelResource> applyFromDevicePool(DeviceId deviceId,
+                                                  long applyNum) {
+        Collection<LabelResource> labelList = new LinkedList<>();
+        LabelResource label = new DefaultLabelResource(deviceId,
+                                  LabelResourceId.labelResourceId(
+                                  getLabelId(LOCAL_LABEL_SPACE_MIN, LOCAL_LABEL_SPACE_MAX)));
+        labelList.add(label);
+        return labelList;
+    }
+
+    public Collection<LabelResource> applyFromGlobalPool(long applyNum) {
+        Collection<LabelResource> labelList = new LinkedList<>();
+        LabelResource label = new DefaultLabelResource(DeviceId.deviceId("foo"),
+                                  LabelResourceId.labelResourceId(
+                                  getLabelId(GLOBAL_LABEL_SPACE_MIN, GLOBAL_LABEL_SPACE_MAX)));
+        labelList.add(label);
+        return labelList;
+    }
+
+    public boolean releaseToDevicePool(Multimap<DeviceId, LabelResource> release) {
+       return true;
+    }
+
+    public boolean releaseToGlobalPool(Set<LabelResourceId> release) {
+       return true;
+    }
+
+    public boolean isDevicePoolFull(DeviceId deviceId) {
+       return false;
+    }
+
+    public boolean isGlobalPoolFull() {
+       return false;
+    }
+
+    public long getFreeNumOfDevicePool(DeviceId deviceId) {
+       return 4;
+    }
+
+    public long getFreeNumOfGlobalPool() {
+       return 4;
+    }
+
+    @Override
+    public LabelResourcePool getDeviceLabelResourcePool(DeviceId deviceId) {
+       return null;
+    }
+
+    @Override
+    public LabelResourcePool getGlobalLabelResourcePool() {
+       return null;
+    }
+
+    private class InternalLabelResourceDelegate implements LabelResourceDelegate {
+        @Override
+        public void notify(LabelResourceEvent event) {
+            post(event);
+        }
+
+    }
+
+    private class InternalDeviceListener implements DeviceListener {
+        @Override
+        public void event(DeviceEvent event) {
+            Device device = event.subject();
+            if (Type.DEVICE_REMOVED.equals(event.type())) {
+                destroyDevicePool(device.id());
+            }
+        }
+    }
+
+    private class InternalLabelResourceProviderService
+            extends AbstractProviderService<LabelResourceProvider>
+            implements LabelResourceProviderService {
+
+        protected InternalLabelResourceProviderService(LabelResourceProvider provider) {
+            super(provider);
+        }
+
+        @Override
+        public void deviceLabelResourcePoolDetected(DeviceId deviceId,
+                                                    LabelResourceId beginLabel,
+                                                    LabelResourceId endLabel) {
+            checkNotNull(deviceId, "deviceId is not null");
+            checkNotNull(beginLabel, "beginLabel is not null");
+            checkNotNull(endLabel, "endLabel is not null");
+            createDevicePool(deviceId, beginLabel, endLabel);
+        }
+
+        @Override
+        public void deviceLabelResourcePoolDestroyed(DeviceId deviceId) {
+            checkNotNull(deviceId, "deviceId is not null");
+            destroyDevicePool(deviceId);
+        }
+
+    }
+
+    @Override
+    protected LabelResourceProviderService createProviderService(LabelResourceProvider provider) {
+        return null;
+    }
+}
