diff --git a/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/BasicPceccHandler.java b/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/BasicPceccHandler.java
new file mode 100644
index 0000000..c547b35
--- /dev/null
+++ b/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/BasicPceccHandler.java
@@ -0,0 +1,579 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * 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.pcep.server.impl;
+
+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.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
+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.IpTunnelEndPoint;
+import org.onosproject.incubator.net.tunnel.Tunnel;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.pcelabelstore.DefaultLspLocalLabelInfo;
+import org.onosproject.pcelabelstore.PcepLabelOp;
+import org.onosproject.pcelabelstore.api.LspLocalLabelInfo;
+import org.onosproject.pcelabelstore.api.PceLabelStore;
+import org.onosproject.pcep.server.LspType;
+import org.onosproject.pcep.server.PccId;
+import org.onosproject.pcep.server.PcepAnnotationKeys;
+import org.onosproject.pcep.server.PcepClient;
+import org.onosproject.pcep.server.PcepClientController;
+import org.onosproject.pcep.server.SrpIdGenerators;
+import org.onosproject.pcepio.exceptions.PcepParseException;
+import org.onosproject.pcepio.protocol.PcepAttribute;
+import org.onosproject.pcepio.protocol.PcepBandwidthObject;
+import org.onosproject.pcepio.protocol.PcepEroObject;
+import org.onosproject.pcepio.protocol.PcepLabelObject;
+import org.onosproject.pcepio.protocol.PcepLabelUpdate;
+import org.onosproject.pcepio.protocol.PcepLabelUpdateMsg;
+import org.onosproject.pcepio.protocol.PcepLspObject;
+import org.onosproject.pcepio.protocol.PcepMsgPath;
+import org.onosproject.pcepio.protocol.PcepSrpObject;
+import org.onosproject.pcepio.protocol.PcepUpdateMsg;
+import org.onosproject.pcepio.protocol.PcepUpdateRequest;
+import org.onosproject.pcepio.types.IPv4SubObject;
+import org.onosproject.pcepio.types.NexthopIPv4addressTlv;
+import org.onosproject.pcepio.types.PathSetupTypeTlv;
+import org.onosproject.pcepio.types.PcepLabelDownload;
+import org.onosproject.pcepio.types.PcepValueType;
+import org.onosproject.pcepio.types.StatefulIPv4LspIdentifiersTlv;
+import org.onosproject.pcepio.types.SymbolicPathNameTlv;
+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;
+
+import static org.onosproject.pcep.server.PcepAnnotationKeys.BANDWIDTH;
+import static org.onosproject.pcep.server.PcepAnnotationKeys.LSP_SIG_TYPE;
+import static org.onosproject.pcep.server.PcepAnnotationKeys.PCE_INIT;
+import static org.onosproject.pcep.server.PcepAnnotationKeys.DELEGATE;
+
+/**
+ * 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);
+    public static final int OUT_LABEL_TYPE = 0;
+    public static final int IN_LABEL_TYPE = 1;
+    public static final long IDENTIFIER_SET = 0x100000000L;
+    public static final long SET = 0xFFFFFFFFL;
+    private static final String LSRID = "lsrId";
+    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 DeviceService deviceService;
+    private PceLabelStore pceStore;
+    private PcepClientController clientController;
+    private PcepLabelObject labelObj;
+
+    /**
+     * 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 deviceService device service
+     * @param pceStore pce label store
+     * @param clientController client controller
+     */
+    public void initialize(LabelResourceService labelRsrcService,
+                           DeviceService deviceService,
+                           PceLabelStore pceStore,
+                           PcepClientController clientController) {
+        this.labelRsrcService = labelRsrcService;
+        this.deviceService = deviceService;
+        this.pceStore = pceStore;
+        this.clientController = clientController;
+    }
+
+    /**
+     * 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.isEmpty())) {
+            // Sequence through reverse order to push local labels into devices
+            // Generation of labels from egress to ingress
+            for (ListIterator<Link> iterator = linkList.listIterator(linkList.size()); iterator.hasPrevious();) {
+                Link link = iterator.previous();
+                DeviceId dstDeviceId = link.dst().deviceId();
+                DeviceId srcDeviceId = link.src().deviceId();
+                labelRscList = labelRsrcService.applyFromDevicePool(dstDeviceId, applyNum);
+                if ((labelRscList != null) && (!labelRscList.isEmpty())) {
+                    // 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;
+                    }
+
+                    try {
+                        // Push into destination device
+                        // Destination device IN port is link.dst().port()
+                        pushLocalLabels(dstDeviceId, labelId, dstPort, tunnel, false,
+                                            Long.valueOf(LabelType.IN_LABEL.value), PcepLabelOp.ADD);
+
+                        // Push into source device
+                        // Source device OUT port will be link.dst().port(). Means its remote port used to send packet.
+                        pushLocalLabels(srcDeviceId, labelId, dstPort, tunnel, isLastLabelToPush,
+                                            Long.valueOf(LabelType.OUT_LABEL.value), PcepLabelOp.ADD);
+                    } catch (PcepParseException e) {
+                        log.error("Failed to push local label for device {} or {} for tunnel {}.",
+                                  dstDeviceId.toString(), srcDeviceId.toString(), tunnel.tunnelName().toString());
+                    }
+
+                    // Add or update pcecc tunnel info in pce store.
+                    updatePceccTunnelInfoInStore(srcDeviceId, dstDeviceId, labelId, dstPort,
+                                                 tunnel);
+                } 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
+     */
+    public void updatePceccTunnelInfoInStore(DeviceId srcDeviceId, DeviceId dstDeviceId, LabelResourceId labelId,
+                                                PortNumber dstPort, Tunnel tunnel) {
+       // 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;
+
+       List<LspLocalLabelInfo> lspLabelInfoList = pceStore.getTunnelInfo(tunnel.tunnelId());
+       if ((lspLabelInfoList != null) && (!lspLabelInfoList.isEmpty())) {
+           for (int i = 0; i < lspLabelInfoList.size(); ++i) {
+               LspLocalLabelInfo lspLocalLabelInfo =
+                       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 (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);
+           }
+
+           pceStore.addTunnelInfo(tunnel.tunnelId(), lspLabelInfoList);
+       }
+    }
+
+    /**
+     * Deallocates unused labels to device pools.
+     *
+     * @param tunnel tunnel between ingress to egress
+     */
+    public void releaseLabel(Tunnel tunnel) {
+
+       checkNotNull(labelRsrcService, LABEL_RESOURCE_SERVICE_NULL);
+       checkNotNull(pceStore, PCE_STORE_NULL);
+
+       Multimap<DeviceId, LabelResource> release = ArrayListMultimap.create();
+       List<LspLocalLabelInfo> lspLocalLabelInfoList = pceStore.getTunnelInfo(tunnel.tunnelId());
+       if ((lspLocalLabelInfoList != null) && (!lspLocalLabelInfoList.isEmpty())) {
+           for (Iterator<LspLocalLabelInfo> iterator = lspLocalLabelInfoList.iterator(); iterator.hasNext();) {
+               LspLocalLabelInfo lspLocalLabelInfo = iterator.next();
+               DeviceId deviceId = lspLocalLabelInfo.deviceId();
+               LabelResourceId inLabelId = lspLocalLabelInfo.inLabelId();
+               LabelResourceId outLabelId = lspLocalLabelInfo.outLabelId();
+               PortNumber inPort = lspLocalLabelInfo.inPort();
+               PortNumber outPort = lspLocalLabelInfo.outPort();
+
+               try {
+                   // Push into device
+                   if ((outLabelId != null) && (outPort != null)) {
+                       pushLocalLabels(deviceId, outLabelId, outPort, tunnel, false,
+                                       Long.valueOf(LabelType.OUT_LABEL.value), PcepLabelOp.REMOVE);
+                   }
+
+                   if ((inLabelId != null) && (inPort != null)) {
+                       pushLocalLabels(deviceId, inLabelId, inPort, tunnel, false,
+                                       Long.valueOf(LabelType.IN_LABEL.value), PcepLabelOp.REMOVE);
+                   }
+               } catch (PcepParseException e) {
+                   log.error("Failed to push local label for device {}for tunnel {}.", deviceId.toString(),
+                             tunnel.tunnelName().toString());
+               }
+
+               // 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);
+       }
+
+       pceStore.removeTunnelInfo(tunnel.tunnelId());
+   }
+
+   //Pushes local labels to the device which is specific to path [CR-case].
+   private void pushLocalLabels(DeviceId deviceId, LabelResourceId labelId,
+            PortNumber portNum, Tunnel tunnel,
+            Boolean isBos, Long labelType, PcepLabelOp type) throws PcepParseException {
+
+        checkNotNull(deviceId);
+        checkNotNull(labelId);
+        checkNotNull(portNum);
+        checkNotNull(tunnel);
+        checkNotNull(labelType);
+        checkNotNull(type);
+
+        PcepClient pc = getPcepClient(deviceId);
+        if (pc == null) {
+            log.error("PCEP client not found");
+            return;
+        }
+
+        PcepLspObject lspObj;
+        LinkedList<PcepLabelUpdate> labelUpdateList = new LinkedList<>();
+        LinkedList<PcepLabelObject> labelObjects = new LinkedList<>();
+        PcepSrpObject srpObj;
+        PcepLabelDownload labelDownload = new PcepLabelDownload();
+        LinkedList<PcepValueType> optionalTlv = new LinkedList<>();
+
+        long portNo = portNum.toLong();
+        portNo = ((portNo & IDENTIFIER_SET) == IDENTIFIER_SET) ? portNo & SET : portNo;
+
+        optionalTlv.add(NexthopIPv4addressTlv.of((int) portNo));
+
+        PcepLabelObject labelObj = pc.factory().buildLabelObject()
+                                   .setOFlag(labelType == OUT_LABEL_TYPE ? true : false)
+                                   .setOptionalTlv(optionalTlv)
+                                   .setLabel((int) labelId.labelId())
+                                   .build();
+
+        /**
+         * Check whether transit node or not. For transit node, label update message should include IN and OUT labels.
+         * Hence store IN label object and next when out label comes add IN and OUT label objects and encode label
+         * update message and send to specified client.
+         */
+        if (!deviceId.equals(tunnel.path().src().deviceId()) && !deviceId.equals(tunnel.path().dst().deviceId())) {
+            //Device is transit node
+            if (labelType == OUT_LABEL_TYPE) {
+                //Store label object having IN label value
+                this.labelObj = labelObj;
+                return;
+            }
+            //Add IN label object
+            labelObjects.add(this.labelObj);
+        }
+
+        //Add OUT label object in case of transit node
+        labelObjects.add(labelObj);
+
+        srpObj = getSrpObject(pc, type, false);
+
+        String lspId = tunnel.annotations().value(PcepAnnotationKeys.LOCAL_LSP_ID);
+        String plspId = tunnel.annotations().value(PcepAnnotationKeys.PLSP_ID);
+        String tunnelIdentifier = tunnel.annotations().value(PcepAnnotationKeys.PCC_TUNNEL_ID);
+
+        LinkedList<PcepValueType> tlvs = new LinkedList<>();
+        StatefulIPv4LspIdentifiersTlv lspIdTlv = new StatefulIPv4LspIdentifiersTlv(((IpTunnelEndPoint) tunnel.src())
+                .ip().getIp4Address().toInt(), Short.valueOf(lspId), Short.valueOf(tunnelIdentifier),
+                ((IpTunnelEndPoint) tunnel.src()).ip().getIp4Address().toInt(),
+                ((IpTunnelEndPoint) tunnel.dst()).ip().getIp4Address().toInt());
+        tlvs.add(lspIdTlv);
+
+        if (tunnel.tunnelName().value() != null) {
+            SymbolicPathNameTlv pathNameTlv = new SymbolicPathNameTlv(tunnel.tunnelName().value().getBytes());
+            tlvs.add(pathNameTlv);
+        }
+
+        boolean delegated = (tunnel.annotations().value(DELEGATE) == null) ? false
+                                                                           : Boolean.valueOf(tunnel.annotations()
+                                                                                   .value(DELEGATE));
+        boolean initiated = (tunnel.annotations().value(PCE_INIT) == null) ? false
+                                                                           : Boolean.valueOf(tunnel.annotations()
+                                                                                   .value(PCE_INIT));
+
+        lspObj = pc.factory().buildLspObject()
+                .setRFlag(false)
+                .setAFlag(true)
+                .setDFlag(delegated)
+                .setCFlag(initiated)
+                .setPlspId(Integer.valueOf(plspId))
+                .setOptionalTlv(tlvs)
+                .build();
+
+        labelDownload.setLabelList(labelObjects);
+        labelDownload.setLspObject(lspObj);
+        labelDownload.setSrpObject(srpObj);
+
+        labelUpdateList.add(pc.factory().buildPcepLabelUpdateObject()
+                            .setLabelDownload(labelDownload)
+                            .build());
+
+        PcepLabelUpdateMsg labelMsg = pc.factory().buildPcepLabelUpdateMsg()
+                                      .setPcLabelUpdateList(labelUpdateList)
+                                      .build();
+
+        pc.sendMessage(labelMsg);
+
+        //If isBos is true, label download is done along the LSP, send PCEP update message.
+        if (isBos) {
+            sendPcepUpdateMsg(pc, lspObj, tunnel);
+        }
+    }
+
+   //Sends PCEP update message.
+   private void sendPcepUpdateMsg(PcepClient pc, PcepLspObject lspObj, Tunnel tunnel) throws PcepParseException {
+       LinkedList<PcepUpdateRequest> updateRequestList = new LinkedList<>();
+       LinkedList<PcepValueType> subObjects = createEroSubObj(tunnel.path());
+
+       if (subObjects == null) {
+           log.error("ERO subjects not present");
+           return;
+       }
+
+       // set PathSetupTypeTlv of SRP object
+       LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();
+       LspType lspSigType = LspType.valueOf(tunnel.annotations().value(LSP_SIG_TYPE));
+       llOptionalTlv.add(new PathSetupTypeTlv(lspSigType.type()));
+
+       PcepSrpObject srpObj = pc.factory().buildSrpObject()
+                              .setRFlag(false)
+                              .setSrpID(SrpIdGenerators.create())
+                              .setOptionalTlv(llOptionalTlv)
+                              .build();
+
+       PcepEroObject eroObj = pc.factory().buildEroObject()
+                             .setSubObjects(subObjects)
+                             .build();
+
+       float  iBandwidth = 0;
+       if (tunnel.annotations().value(BANDWIDTH) != null) {
+           //iBandwidth = Float.floatToIntBits(Float.parseFloat(tunnel.annotations().value(BANDWIDTH)));
+           iBandwidth = Float.parseFloat(tunnel.annotations().value(BANDWIDTH));
+       }
+       // build bandwidth object
+       PcepBandwidthObject bandwidthObject = pc.factory().buildBandwidthObject()
+                                             .setBandwidth(iBandwidth)
+                                             .build();
+       // build pcep attribute
+       PcepAttribute pcepAttribute = pc.factory().buildPcepAttribute()
+                                     .setBandwidthObject(bandwidthObject)
+                                     .build();
+
+       PcepMsgPath msgPath = pc.factory().buildPcepMsgPath()
+                             .setEroObject(eroObj)
+                             .setPcepAttribute(pcepAttribute)
+                             .build();
+
+       PcepUpdateRequest updateReq = pc.factory().buildPcepUpdateRequest()
+                                    .setSrpObject(srpObj)
+                                    .setMsgPath(msgPath)
+                                    .setLspObject(lspObj)
+                                    .build();
+
+       updateRequestList.add(updateReq);
+
+       //TODO: P = 1 is it P flag in PCEP obj header
+       PcepUpdateMsg updateMsg = pc.factory().buildUpdateMsg()
+                                 .setUpdateRequestList(updateRequestList)
+                                 .build();
+
+       pc.sendMessage(updateMsg);
+   }
+
+   private LinkedList<PcepValueType> createEroSubObj(Path path) {
+       LinkedList<PcepValueType> subObjects = new LinkedList<>();
+       List<Link> links = path.links();
+       ConnectPoint source = null;
+       ConnectPoint destination = null;
+       IpAddress ipDstAddress = null;
+       IpAddress ipSrcAddress = null;
+       PcepValueType subObj = null;
+       long portNo;
+
+       for (Link link : links) {
+           source = link.src();
+           if (!(source.equals(destination))) {
+               //set IPv4SubObject for ERO object
+               portNo = source.port().toLong();
+               portNo = ((portNo & IDENTIFIER_SET) == IDENTIFIER_SET) ? portNo & SET : portNo;
+               ipSrcAddress = Ip4Address.valueOf((int) portNo);
+               subObj = new IPv4SubObject(ipSrcAddress.getIp4Address().toInt());
+               subObjects.add(subObj);
+           }
+
+           destination = link.dst();
+           portNo = destination.port().toLong();
+           portNo = ((portNo & IDENTIFIER_SET) == IDENTIFIER_SET) ? portNo & SET : portNo;
+           ipDstAddress = Ip4Address.valueOf((int) portNo);
+           subObj = new IPv4SubObject(ipDstAddress.getIp4Address().toInt());
+           subObjects.add(subObj);
+       }
+       return subObjects;
+   }
+
+   private PcepSrpObject getSrpObject(PcepClient pc, PcepLabelOp type, boolean bSFlag)
+           throws PcepParseException {
+       PcepSrpObject srpObj;
+       boolean bRFlag = false;
+
+       if (!type.equals(PcepLabelOp.ADD)) {
+           // To cleanup labels, R bit is set
+           bRFlag = true;
+       }
+
+       srpObj = pc.factory().buildSrpObject()
+               .setRFlag(bRFlag)
+               .setSFlag(bSFlag)
+               .setSrpID(SrpIdGenerators.create())
+               .build();
+
+       return srpObj;
+   }
+
+   /**
+    * Returns PCEP client.
+    *
+    * @return PCEP client
+    */
+   private PcepClient getPcepClient(DeviceId deviceId) {
+       Device device = deviceService.getDevice(deviceId);
+
+       // In future projections instead of annotations will be used to fetch LSR ID.
+       String lsrId = device.annotations().value(LSRID);
+       PcepClient pcc = clientController.getClient(PccId.pccId(IpAddress.valueOf(lsrId)));
+       return pcc;
+   }
+}
diff --git a/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/Controller.java b/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/Controller.java
new file mode 100644
index 0000000..c85e22a
--- /dev/null
+++ b/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/Controller.java
@@ -0,0 +1,290 @@
+/*
+ * Copyright 2015-present Open Networking Foundation
+ *
+ * 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.pcep.server.impl;
+
+import static org.onlab.util.Tools.groupedThreads;
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.RuntimeMXBean;
+import java.net.InetSocketAddress;
+import java.util.Map;
+import java.util.LinkedList;
+import java.util.TreeMap;
+import java.util.List;
+import java.util.HashMap;
+import java.util.concurrent.Executors;
+
+import org.jboss.netty.bootstrap.ServerBootstrap;
+import org.jboss.netty.channel.ChannelPipelineFactory;
+import org.jboss.netty.channel.group.ChannelGroup;
+import org.jboss.netty.channel.group.DefaultChannelGroup;
+import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
+import org.onosproject.pcep.server.PccId;
+import org.onosproject.pcep.server.PcepCfg;
+import org.onosproject.pcep.server.PcepPacketStats;
+import org.onosproject.pcep.server.driver.PcepAgent;
+import org.onosproject.pcep.server.driver.PcepClientDriver;
+import org.onosproject.pcepio.protocol.PcepFactories;
+import org.onosproject.pcepio.protocol.PcepFactory;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The main controller class. Handles all setup and network listeners -
+ * Distributed ownership control of pcc through IControllerRegistryService
+ */
+public class Controller {
+
+    private static final Logger log = LoggerFactory.getLogger(Controller.class);
+
+    private static final PcepFactory FACTORY1 = PcepFactories.getFactory(PcepVersion.PCEP_1);
+    private PcepCfg pcepConfig = new PcepConfig();
+    private ChannelGroup cg;
+
+    // Configuration options
+    private int pcepPort = 4189;
+    private int workerThreads = 10;
+
+    // Start time of the controller
+    private long systemStartTime;
+
+    private PcepAgent agent;
+
+    private Map<String, String> peerMap = new TreeMap<>();
+    private Map<String, List<String>> pcepExceptionMap = new TreeMap<>();
+    private Map<Integer, Integer> pcepErrorMsg = new TreeMap<>();
+    private Map<String, Byte> sessionMap = new TreeMap<>();
+    private LinkedList<String> pcepExceptionList = new LinkedList<String>();
+
+    private NioServerSocketChannelFactory execFactory;
+
+    // Perf. related configuration
+    private static final int SEND_BUFFER_SIZE = 4 * 1024 * 1024;
+
+    /**
+     * pcep session information.
+     *
+     * @param peerId id of the peer with which the session is being formed
+     * @param status pcep session status
+     * @param sessionId pcep session id
+     */
+    public void peerStatus(String peerId, String status, byte sessionId) {
+        if (peerId != null) {
+            peerMap.put(peerId, status);
+            sessionMap.put(peerId, sessionId);
+        } else {
+            log.debug("Peer Id is null");
+        }
+    }
+
+    /**
+     * Pcep session exceptions information.
+     *
+     * @param peerId id of the peer which has generated the exception
+     * @param exception pcep session exception
+     */
+    public void peerExceptions(String peerId, String exception) {
+        if (peerId != null) {
+            pcepExceptionList.add(exception);
+            pcepExceptionMap.put(peerId, pcepExceptionList);
+        } else {
+            log.debug("Peer Id is null");
+        }
+        if (pcepExceptionList.size() > 10) {
+            pcepExceptionList.clear();
+            pcepExceptionList.add(exception);
+            pcepExceptionMap.put(peerId, pcepExceptionList);
+        }
+    }
+
+    /**
+     * Create a map of pcep error messages received.
+     *
+     * @param peerId id of the peer which has sent the error message
+     * @param errorType error type of pcep error messgae
+     * @param errValue error value of pcep error messgae
+     */
+    public void peerErrorMsg(String peerId, Integer errorType, Integer errValue) {
+        if (peerId == null) {
+            pcepErrorMsg.put(errorType, errValue);
+        } else {
+            if (pcepErrorMsg.size() > 10) {
+                pcepErrorMsg.clear();
+            }
+            pcepErrorMsg.put(errorType, errValue);
+        }
+    }
+
+    /**
+     * Returns the pcep session details.
+     *
+     * @return pcep session details
+     */
+    public Map<String, Byte> mapSession() {
+        return this.sessionMap;
+    }
+
+
+
+    /**
+     * Returns factory version for processing pcep messages.
+     *
+     * @return instance of factory version
+     */
+    public PcepFactory getPcepMessageFactory1() {
+        return FACTORY1;
+    }
+
+    /**
+     * To get system start time.
+     *
+     * @return system start time in milliseconds
+     */
+    public long getSystemStartTime() {
+        return (this.systemStartTime);
+    }
+
+    /**
+     * Returns the list of pcep peers with session information.
+     *
+     * @return pcep peer information
+     */
+    public  Map<String, String> mapPeer() {
+        return this.peerMap;
+    }
+
+    /**
+     * Returns the list of pcep exceptions per peer.
+     *
+     * @return pcep exceptions
+     */
+    public  Map<String, List<String>> exceptionsMap() {
+        return this.pcepExceptionMap;
+    }
+
+    /**
+     * Returns the type and value of pcep error messages.
+     *
+     * @return pcep error message
+     */
+    public Map<Integer, Integer> mapErrorMsg() {
+        return this.pcepErrorMsg;
+    }
+
+    /**
+     * Tell controller that we're ready to accept pcc connections.
+     */
+    public void run() {
+        try {
+            final ServerBootstrap bootstrap = createServerBootStrap();
+
+            bootstrap.setOption("reuseAddr", true);
+            bootstrap.setOption("child.keepAlive", true);
+            bootstrap.setOption("child.tcpNoDelay", true);
+            bootstrap.setOption("child.sendBufferSize", Controller.SEND_BUFFER_SIZE);
+
+            ChannelPipelineFactory pfact = new PcepPipelineFactory(this);
+
+            bootstrap.setPipelineFactory(pfact);
+            InetSocketAddress sa = new InetSocketAddress(pcepPort);
+            cg = new DefaultChannelGroup();
+            cg.add(bootstrap.bind(sa));
+            log.debug("Listening for PCC connection on {}", sa);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Creates server boot strap.
+     *
+     * @return ServerBootStrap
+     */
+    private ServerBootstrap createServerBootStrap() {
+        if (workerThreads == 0) {
+            execFactory = new NioServerSocketChannelFactory(
+                    Executors.newCachedThreadPool(groupedThreads("onos/pcep", "boss-%d")),
+                    Executors.newCachedThreadPool(groupedThreads("onos/pcep", "worker-%d")));
+            return new ServerBootstrap(execFactory);
+        } else {
+            execFactory = new NioServerSocketChannelFactory(
+                    Executors.newCachedThreadPool(groupedThreads("onos/pcep", "boss-%d")),
+                    Executors.newCachedThreadPool(groupedThreads("onos/pcep", "worker-%d")), workerThreads);
+            return new ServerBootstrap(execFactory);
+        }
+    }
+
+    /**
+     * Initialize internal data structures.
+     */
+    public void init() {
+        // These data structures are initialized here because other
+        // module's startUp() might be called before ours
+        this.systemStartTime = System.currentTimeMillis();
+    }
+
+    public Map<String, Long> getMemory() {
+        Map<String, Long> m = new HashMap<>();
+        Runtime runtime = Runtime.getRuntime();
+        m.put("total", runtime.totalMemory());
+        m.put("free", runtime.freeMemory());
+        return m;
+    }
+
+    public Long getUptime() {
+        RuntimeMXBean rb = ManagementFactory.getRuntimeMXBean();
+        return rb.getUptime();
+    }
+
+    /**
+     * Creates instance of Pcep client.
+     *
+     * @param pccId pcc identifier
+     * @param sessionID session id
+     * @param pv pcep version
+     * @param pktStats pcep packet statistics
+     * @return instance of PcepClient
+     */
+    protected PcepClientDriver getPcepClientInstance(PccId pccId, int sessionID, PcepVersion pv,
+            PcepPacketStats pktStats) {
+        PcepClientDriver pcepClientDriver = new PcepClientImpl();
+        pcepClientDriver.init(pccId, pv, pktStats);
+        pcepClientDriver.setAgent(agent);
+        return pcepClientDriver;
+    }
+
+    /**
+     * Starts the pcep controller.
+     *
+     * @param ag Pcep agent
+     */
+    public void start(PcepAgent ag) {
+        log.info("Started");
+        this.agent = ag;
+        this.init();
+        this.run();
+    }
+
+    /**
+     * Stops the pcep controller.
+     */
+    public void stop() {
+        log.info("Stopped");
+        execFactory.shutdown();
+        cg.close();
+    }
+}
diff --git a/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/LabelType.java b/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/LabelType.java
new file mode 100644
index 0000000..ca7cc7c
--- /dev/null
+++ b/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/LabelType.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * 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.pcep.server.impl;
+
+/**
+ * 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/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/PceccSrTeBeHandler.java b/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/PceccSrTeBeHandler.java
new file mode 100644
index 0000000..8d50149
--- /dev/null
+++ b/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/PceccSrTeBeHandler.java
@@ -0,0 +1,585 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * 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.pcep.server.impl;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.pcep.server.PcepSyncStatus.IN_SYNC;
+import static org.onosproject.pcep.server.PcepSyncStatus.SYNCED;
+
+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.onlab.packet.IpAddress;
+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.device.DeviceService;
+import org.onosproject.pcelabelstore.PcepLabelOp;
+import org.onosproject.pcelabelstore.api.PceLabelStore;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.Path;
+import org.onosproject.pcep.server.PccId;
+import org.onosproject.pcep.server.PcepClient;
+import org.onosproject.pcep.server.PcepClientController;
+import org.onosproject.pcep.server.SrpIdGenerators;
+import org.onosproject.pcepio.exceptions.PcepParseException;
+import org.onosproject.pcepio.protocol.PcepFecObjectIPv4;
+import org.onosproject.pcepio.protocol.PcepFecObjectIPv4Adjacency;
+import org.onosproject.pcepio.protocol.PcepLabelObject;
+import org.onosproject.pcepio.protocol.PcepLabelUpdate;
+import org.onosproject.pcepio.protocol.PcepLabelUpdateMsg;
+import org.onosproject.pcepio.protocol.PcepSrpObject;
+import org.onosproject.pcepio.types.PcepLabelMap;
+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_ID_NULL = "Device-Id cannot be null";
+    private static final String LSR_ID_NULL = "LSR-Id 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 PceccSrTeBeHandler srTeHandlerInstance = null;
+    private LabelResourceAdminService labelRsrcAdminService;
+    private LabelResourceService labelRsrcService;
+    private DeviceService deviceService;
+    private PcepClientController clientController;
+    private PceLabelStore 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 clientController client controller
+     * @param pceStore PCE label store
+     * @param deviceService device service
+     */
+    public void initialize(LabelResourceAdminService labelRsrcAdminService,
+                           LabelResourceService labelRsrcService,
+                           PcepClientController clientController,
+                           PceLabelStore pceStore,
+                           DeviceService deviceService) {
+        this.labelRsrcAdminService = labelRsrcAdminService;
+        this.labelRsrcService = labelRsrcService;
+        this.clientController = clientController;
+        this.pceStore = pceStore;
+        this.deviceService = deviceService;
+    }
+
+    /**
+     * 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));
+    }
+
+    /**
+     * Retrieve lsr-id from device annotation.
+     *
+     * @param deviceId specific device id from which lsr-id needs to be retrieved
+     * @return lsr-id of a device
+     */
+    public String getLsrId(DeviceId deviceId) {
+        checkNotNull(deviceId, DEVICE_ID_NULL);
+        Device device = deviceService.getDevice(deviceId);
+        if (device == null) {
+            log.debug("Device is not available for device id {} in device service.", deviceId.toString());
+            return null;
+        }
+
+        // Retrieve lsr-id from device
+        if (device.annotations() == null) {
+            log.debug("Device {} does not have annotation.", device.toString());
+            return null;
+        }
+
+        String lsrId = device.annotations().value(LSR_ID);
+        if (lsrId == null) {
+            log.debug("The lsr-id of device {} is null.", device.toString());
+            return null;
+        }
+        return lsrId;
+    }
+
+    /**
+     * 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
+     * @return success or failure
+     */
+    public boolean allocateNodeLabel(DeviceId specificDeviceId, String specificLsrId) {
+        long applyNum = 1; // For each node only one node label
+        LabelResourceId specificLabelId = null;
+
+        checkNotNull(specificDeviceId, DEVICE_ID_NULL);
+        checkNotNull(specificLsrId, LSR_ID_NULL);
+        checkNotNull(labelRsrcService, LABEL_RESOURCE_SERVICE_NULL);
+        checkNotNull(pceStore, PCE_STORE_NULL);
+
+        // Check whether node-label was already configured for this specific device.
+        if (pceStore.getGlobalNodeLabel(specificDeviceId) != null) {
+            log.debug("Node label was already configured for device {}.", specificDeviceId.toString());
+            return false;
+        }
+
+        // The specificDeviceId is the new device and is not there in the pce store.
+        // So, first generate its label and configure label and its lsr-id to it.
+        Collection<LabelResource> result = labelRsrcService.applyFromGlobalPool(applyNum);
+        if (!result.isEmpty()) {
+            // 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;
+        }
+
+        // store it
+        pceStore.addGlobalNodeLabel(specificDeviceId, specificLabelId);
+
+        // Push its label information into specificDeviceId
+        PcepClient pcc = getPcepClient(specificDeviceId);
+        try {
+            pushGlobalNodeLabel(pcc,
+                                specificLabelId,
+                                IpAddress.valueOf(specificLsrId).getIp4Address().toInt(),
+                                PcepLabelOp.ADD,
+                                false);
+        } catch (PcepParseException e) {
+            log.error("Failed to push global node label for LSR {}.", specificLsrId.toString());
+        }
+
+        // Configure (node-label, lsr-id) mapping of each devices into specific device and vice versa.
+        for (Map.Entry<DeviceId, LabelResourceId> element : pceStore.getGlobalNodeLabels().entrySet()) {
+            DeviceId otherDevId = element.getKey();
+
+            // Get lsr-id of a device
+            String otherLsrId = getLsrId(otherDevId);
+            if (otherLsrId == null) {
+                log.error("The lsr-id of device id {} is null.", otherDevId.toString());
+                releaseNodeLabel(specificDeviceId, specificLsrId);
+                return false;
+            }
+
+            // Push to device
+            // Push label information of specificDeviceId to otherDevId in list and vice versa.
+            if (!otherDevId.equals(specificDeviceId)) {
+                try {
+                    pushGlobalNodeLabel(getPcepClient(otherDevId),
+                                        specificLabelId,
+                                        IpAddress.valueOf(specificLsrId).getIp4Address().toInt(),
+                                        PcepLabelOp.ADD,
+                                        false);
+
+                    pushGlobalNodeLabel(pcc, element.getValue(),
+                                        IpAddress.valueOf(otherLsrId).getIp4Address().toInt(),
+                                        PcepLabelOp.ADD,
+                                        false);
+                } catch (PcepParseException e) {
+                    log.error("Failed to push global node label for LSR {} or LSR {}.", specificLsrId.toString(),
+                              otherLsrId.toString());
+                }
+            }
+        }
+        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
+     * @return success or failure
+     */
+    public boolean releaseNodeLabel(DeviceId specificDeviceId, String specificLsrId) {
+        checkNotNull(specificDeviceId, DEVICE_ID_NULL);
+        checkNotNull(specificLsrId, LSR_ID_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 pce store and remove label entry from device
+        for (Map.Entry<DeviceId, LabelResourceId> element : pceStore.getGlobalNodeLabels().entrySet()) {
+            DeviceId otherDevId = element.getKey();
+
+            // Remove this specific device label information from all other nodes except
+            // this specific node where connection already lost.
+            if (!specificDeviceId.equals(otherDevId)) {
+                try {
+                    pushGlobalNodeLabel(getPcepClient(otherDevId),
+                                        labelId,
+                                        IpAddress.valueOf(specificLsrId).getIp4Address().toInt(),
+                                        PcepLabelOp.REMOVE,
+                                        false);
+                } catch (PcepParseException e) {
+                    log.error("Failed to push global node label for LSR {}.", specificLsrId.toString());
+                }
+            }
+        }
+
+        // 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);
+
+        // Checks whether adjacency label was already allocated
+        LabelResourceId labelId = pceStore.getAdjLabel(link);
+        if (labelId != null) {
+            log.debug("Adjacency label {} was already allocated for a link {}.", labelId.toString(), link.toString());
+            return false;
+        }
+
+        // Allocate adjacency label to a link from label manager.
+        // Take label from source device pool to allocate.
+        labelList = labelRsrcService.applyFromDevicePool(srcDeviceId, applyNum);
+        if (labelList.isEmpty()) {
+            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();
+        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
+        try {
+            pushAdjacencyLabel(getPcepClient(srcDeviceId), labelId, (int) link.src().port().toLong(),
+                               (int) link.dst().port().toLong(), PcepLabelOp.ADD);
+        } catch (PcepParseException e) {
+            log.error("Failed to push adjacency label for link {}-{}.", (int) link.src().port().toLong(),
+                      (int) link.dst().port().toLong());
+        }
+
+        // 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
+        try {
+            pushAdjacencyLabel(getPcepClient(srcDeviceId), labelId, (int) link.src().port().toLong(),
+                               (int) link.dst().port().toLong(), PcepLabelOp.REMOVE);
+        } catch (PcepParseException e) {
+            log.error("Failed to push adjacency label for link {}-{}.", (int) link.src().port().toLong(),
+                      (int) link.dst().port().toLong());
+        }
+
+
+        // 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.isEmpty())) {
+            // 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 = iterator.next();
+                // 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);
+
+                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);
+    }
+
+    //Pushes node labels to the specified device.
+    void pushGlobalNodeLabel(PcepClient pc, LabelResourceId labelId,
+            int labelForNode, PcepLabelOp type, boolean isBos) throws PcepParseException {
+
+        checkNotNull(pc);
+        checkNotNull(labelId);
+        checkNotNull(type);
+
+        LinkedList<PcepLabelUpdate> labelUpdateList = new LinkedList<>();
+        PcepFecObjectIPv4 fecObject = pc.factory().buildFecObjectIpv4()
+                                      .setNodeID(labelForNode)
+                                      .build();
+
+        boolean bSFlag = false;
+        if (pc.labelDbSyncStatus() == IN_SYNC && !isBos) {
+            // Need to set sync flag in all messages till sync completes.
+            bSFlag = true;
+        }
+
+        PcepSrpObject srpObj = getSrpObject(pc, type, bSFlag);
+
+        //Global NODE-SID as label object
+        PcepLabelObject labelObject = pc.factory().buildLabelObject()
+                                      .setLabel((int) labelId.labelId())
+                                      .build();
+
+        PcepLabelMap labelMap = new PcepLabelMap();
+        labelMap.setFecObject(fecObject);
+        labelMap.setLabelObject(labelObject);
+        labelMap.setSrpObject(srpObj);
+
+        labelUpdateList.add(pc.factory().buildPcepLabelUpdateObject()
+                            .setLabelMap(labelMap)
+                            .build());
+
+        PcepLabelUpdateMsg labelMsg = pc.factory().buildPcepLabelUpdateMsg()
+                                      .setPcLabelUpdateList(labelUpdateList)
+                                      .build();
+        pc.sendMessage(labelMsg);
+
+        if (isBos) {
+            // Sync is completed.
+            pc.setLabelDbSyncStatus(SYNCED);
+        }
+    }
+
+    //Pushes adjacency labels to the specified device.
+    void pushAdjacencyLabel(PcepClient pc, LabelResourceId labelId, int srcPortNo,
+                                    int dstPortNo, PcepLabelOp type)
+            throws PcepParseException {
+
+        checkNotNull(pc);
+        checkNotNull(labelId);
+        checkNotNull(type);
+
+        LinkedList<PcepLabelUpdate> labelUpdateList = new LinkedList<>();
+        PcepFecObjectIPv4Adjacency fecAdjObject = pc.factory().buildFecIpv4Adjacency()
+                                                  .seRemoteIPv4Address(dstPortNo)
+                                                  .seLocalIPv4Address(srcPortNo)
+                                                  .build();
+
+        boolean bSFlag = false;
+        if (pc.labelDbSyncStatus() == IN_SYNC) {
+            // Need to set sync flag in all messages till sync completes.
+            bSFlag = true;
+        }
+
+        PcepSrpObject srpObj = getSrpObject(pc, type, bSFlag);
+
+        //Adjacency label object
+        PcepLabelObject labelObject = pc.factory().buildLabelObject()
+                                      .setLabel((int) labelId.labelId())
+                                      .build();
+
+        PcepLabelMap labelMap = new PcepLabelMap();
+        labelMap.setFecObject(fecAdjObject);
+        labelMap.setLabelObject(labelObject);
+        labelMap.setSrpObject(srpObj);
+
+        labelUpdateList.add(pc.factory().buildPcepLabelUpdateObject()
+                            .setLabelMap(labelMap)
+                            .build());
+
+        PcepLabelUpdateMsg labelMsg = pc.factory().buildPcepLabelUpdateMsg()
+                                      .setPcLabelUpdateList(labelUpdateList)
+                                      .build();
+        pc.sendMessage(labelMsg);
+    }
+
+    private PcepSrpObject getSrpObject(PcepClient pc, PcepLabelOp type, boolean bSFlag)
+            throws PcepParseException {
+        PcepSrpObject srpObj;
+        boolean bRFlag = false;
+
+        if (!type.equals(PcepLabelOp.ADD)) {
+            // To cleanup labels, R bit is set
+            bRFlag = true;
+        }
+
+        srpObj = pc.factory().buildSrpObject()
+                .setRFlag(bRFlag)
+                .setSFlag(bSFlag)
+                .setSrpID(SrpIdGenerators.create())
+                .build();
+
+        return srpObj;
+    }
+
+    /**
+     * Returns PCEP client.
+     *
+     * @return PCEP client
+     */
+    private PcepClient getPcepClient(DeviceId deviceId) {
+        Device device = deviceService.getDevice(deviceId);
+
+        // In future projections instead of annotations will be used to fetch LSR ID.
+        String lsrId = device.annotations().value(LSR_ID);
+        PcepClient pcc = clientController.getClient(PccId.pccId(IpAddress.valueOf(lsrId)));
+        return pcc;
+    }
+}
diff --git a/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/PcepChannelHandler.java b/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/PcepChannelHandler.java
new file mode 100644
index 0000000..dce5fa0
--- /dev/null
+++ b/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/PcepChannelHandler.java
@@ -0,0 +1,725 @@
+/*
+ * Copyright 2015-present Open Networking Foundation
+ *
+ * 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.pcep.server.impl;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.nio.channels.ClosedChannelException;
+import java.util.Collections;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.concurrent.RejectedExecutionException;
+
+import org.jboss.netty.channel.Channel;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.channel.ChannelStateEvent;
+import org.jboss.netty.channel.ExceptionEvent;
+import org.jboss.netty.channel.MessageEvent;
+import org.jboss.netty.handler.timeout.IdleState;
+import org.jboss.netty.handler.timeout.IdleStateAwareChannelHandler;
+import org.jboss.netty.handler.timeout.IdleStateEvent;
+import org.jboss.netty.handler.timeout.IdleStateHandler;
+import org.jboss.netty.handler.timeout.ReadTimeoutException;
+import org.onlab.packet.IpAddress;
+import org.onosproject.pcep.server.ClientCapability;
+import org.onosproject.pcep.server.PccId;
+import org.onosproject.pcep.server.PcepCfg;
+import org.onosproject.pcep.server.driver.PcepClientDriver;
+import org.onosproject.pcepio.exceptions.PcepParseException;
+import org.onosproject.pcepio.protocol.PcepError;
+import org.onosproject.pcepio.protocol.PcepErrorInfo;
+import org.onosproject.pcepio.protocol.PcepErrorMsg;
+import org.onosproject.pcepio.protocol.PcepErrorObject;
+import org.onosproject.pcepio.protocol.PcepFactory;
+import org.onosproject.pcepio.protocol.PcepMessage;
+import org.onosproject.pcepio.protocol.PcepOpenMsg;
+import org.onosproject.pcepio.protocol.PcepOpenObject;
+import org.onosproject.pcepio.protocol.PcepType;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.onosproject.pcepio.types.IPv4RouterIdOfLocalNodeSubTlv;
+import org.onosproject.pcepio.types.NodeAttributesTlv;
+import org.onosproject.pcepio.types.PceccCapabilityTlv;
+import org.onosproject.pcepio.types.SrPceCapabilityTlv;
+import org.onosproject.pcepio.types.StatefulPceCapabilityTlv;
+import org.onosproject.pcepio.types.PcepErrorDetailInfo;
+import org.onosproject.pcepio.types.PcepValueType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.onosproject.pcep.server.PcepSyncStatus.NOT_SYNCED;
+
+/**
+ * Channel handler deals with the pcc client connection and dispatches
+ * messages from client to the appropriate locations.
+ */
+class PcepChannelHandler extends IdleStateAwareChannelHandler {
+    static final byte DEADTIMER_MAXIMUM_VALUE = (byte) 0xFF;
+    static final byte KEEPALIVE_MULTIPLE_FOR_DEADTIMER = 4;
+    private static final Logger log = LoggerFactory.getLogger(PcepChannelHandler.class);
+    private final Controller controller;
+    private PcepClientDriver pc;
+    private PccId thispccId;
+    private Channel channel;
+    private byte sessionId = 0;
+    private byte keepAliveTime;
+    private byte deadTime;
+    private ClientCapability capability;
+    private PcepPacketStatsImpl pcepPacketStats;
+    static final int MAX_WRONG_COUNT_PACKET = 5;
+    static final int BYTE_MASK = 0xFF;
+
+    // State needs to be volatile because the HandshakeTimeoutHandler
+    // needs to check if the handshake is complete
+    private volatile ChannelState state;
+    private String peerAddr;
+    private SocketAddress address;
+    private InetSocketAddress inetAddress;
+    // When a pcc client with a ip addresss is found (i.e we already have a
+    // connected client with the same ip), the new client is immediately
+    // disconnected. At that point netty callsback channelDisconnected() which
+    // proceeds to cleaup client state - we need to ensure that it does not cleanup
+    // client state for the older (still connected) client
+    private volatile Boolean duplicatePccIdFound;
+
+    //Indicates the pcep version used by this pcc client
+    protected PcepVersion pcepVersion;
+    protected PcepFactory factory1;
+
+    /**
+     * Create a new unconnected PcepChannelHandler.
+     * @param controller parent controller
+     */
+    PcepChannelHandler(Controller controller) {
+        this.controller = controller;
+        this.state = ChannelState.INIT;
+        factory1 = controller.getPcepMessageFactory1();
+        duplicatePccIdFound = Boolean.FALSE;
+        pcepPacketStats = new PcepPacketStatsImpl();
+    }
+
+    /**
+     * To disconnect a PCC.
+     */
+    public void disconnectClient() {
+        pc.disconnectClient();
+    }
+
+    //*************************
+    //  Channel State Machine
+    //*************************
+
+    @Override
+    public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
+        channel = e.getChannel();
+        log.info("PCC connected from {}", channel.getRemoteAddress());
+
+        address = channel.getRemoteAddress();
+        if (!(address instanceof InetSocketAddress)) {
+            throw new IOException("Invalid peer connection.");
+        }
+
+        inetAddress = (InetSocketAddress) address;
+        peerAddr = IpAddress.valueOf(inetAddress.getAddress()).toString();
+
+        // Wait for open message from pcc client
+        setState(ChannelState.OPENWAIT);
+        controller.peerStatus(peerAddr, PcepCfg.State.OPENWAIT.toString(), sessionId);
+    }
+
+    @Override
+    public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
+        log.info("Pcc disconnected callback for pc:{}. Cleaning up ...", getClientInfoString());
+        controller.peerStatus(peerAddr, PcepCfg.State.DOWN.toString(), sessionId);
+
+        channel = e.getChannel();
+        address = channel.getRemoteAddress();
+        if (!(address instanceof InetSocketAddress)) {
+            throw new IOException("Invalid peer connection.");
+        }
+
+        inetAddress = (InetSocketAddress) address;
+        peerAddr = IpAddress.valueOf(inetAddress.getAddress()).toString();
+
+        if (thispccId != null) {
+            if (!duplicatePccIdFound) {
+                // if the disconnected client (on this ChannelHandler)
+                // was not one with a duplicate-dpid, it is safe to remove all
+                // state for it at the controller. Notice that if the disconnected
+                // client was a duplicate-ip, calling the method below would clear
+                // all state for the original client (with the same ip),
+                // which we obviously don't want.
+                log.debug("{}:removal called", getClientInfoString());
+                if (pc != null) {
+                    pc.removeConnectedClient();
+                }
+            } else {
+                // A duplicate was disconnected on this ChannelHandler,
+                // this is the same client reconnecting, but the original state was
+                // not cleaned up - XXX check liveness of original ChannelHandler
+                log.debug("{}:duplicate found", getClientInfoString());
+                duplicatePccIdFound = Boolean.FALSE;
+            }
+        } else {
+            log.warn("no pccip in channelHandler registered for " + "disconnected client {}", getClientInfoString());
+        }
+    }
+
+    @Override
+    public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
+        PcepErrorMsg errMsg;
+        log.info("exceptionCaught: " + e.toString());
+
+        if (e.getCause() instanceof ReadTimeoutException) {
+            if (ChannelState.OPENWAIT == state) {
+                // When ReadTimeout timer is expired in OPENWAIT state, it is considered
+                // OpenWait timer.
+                errMsg = getErrorMsg(PcepErrorDetailInfo.ERROR_TYPE_1, PcepErrorDetailInfo.ERROR_VALUE_2);
+                log.debug("Sending PCEP-ERROR message to PCC.");
+                controller.peerExceptions(peerAddr, e.getCause().toString());
+                channel.write(Collections.singletonList(errMsg));
+                channel.close();
+                state = ChannelState.INIT;
+                return;
+            } else if (ChannelState.KEEPWAIT == state) {
+                // When ReadTimeout timer is expired in KEEPWAIT state, is is considered
+                // KeepWait timer.
+                errMsg = getErrorMsg(PcepErrorDetailInfo.ERROR_TYPE_1, PcepErrorDetailInfo.ERROR_VALUE_7);
+                log.debug("Sending PCEP-ERROR message to PCC.");
+                controller.peerExceptions(peerAddr, e.getCause().toString());
+                channel.write(Collections.singletonList(errMsg));
+                channel.close();
+                state = ChannelState.INIT;
+                return;
+            }
+        } else if (e.getCause() instanceof ClosedChannelException) {
+            controller.peerExceptions(peerAddr, e.getCause().toString());
+            log.debug("Channel for pc {} already closed", getClientInfoString());
+        } else if (e.getCause() instanceof IOException) {
+            controller.peerExceptions(peerAddr, e.getCause().toString());
+            log.error("Disconnecting client {} due to IO Error: {}", getClientInfoString(), e.getCause().getMessage());
+            if (log.isDebugEnabled()) {
+                // still print stack trace if debug is enabled
+                log.debug("StackTrace for previous Exception: ", e.getCause());
+            }
+            channel.close();
+        } else if (e.getCause() instanceof PcepParseException) {
+            controller.peerExceptions(peerAddr, e.getCause().toString());
+            PcepParseException errMsgParse = (PcepParseException) e.getCause();
+            byte errorType = errMsgParse.getErrorType();
+            byte errorValue = errMsgParse.getErrorValue();
+
+            if ((errorType == (byte) 0x0) && (errorValue == (byte) 0x0)) {
+                processUnknownMsg();
+            } else {
+                errMsg = getErrorMsg(errorType, errorValue);
+                log.debug("Sending PCEP-ERROR message to PCC.");
+                channel.write(Collections.singletonList(errMsg));
+            }
+        } else if (e.getCause() instanceof RejectedExecutionException) {
+            log.warn("Could not process message: queue full");
+            controller.peerExceptions(peerAddr, e.getCause().toString());
+        } else {
+            log.error("Error while processing message from client " + getClientInfoString() + "state " + this.state);
+            controller.peerExceptions(peerAddr, e.getCause().toString());
+            channel.close();
+        }
+    }
+
+    @Override
+    public String toString() {
+        return getClientInfoString();
+    }
+
+    @Override
+    public void channelIdle(ChannelHandlerContext ctx, IdleStateEvent e) throws Exception {
+        if (!isHandshakeComplete()) {
+            return;
+        }
+
+        if (e.getState() == IdleState.READER_IDLE) {
+            // When no message is received on channel for read timeout, then close
+            // the channel
+            log.info("Disconnecting client {} due to read timeout", getClientInfoString());
+            ctx.getChannel().close();
+        } else if (e.getState() == IdleState.WRITER_IDLE) {
+            // Send keep alive message
+            log.debug("Sending keep alive message due to IdleState timeout " + pc.toString());
+            pc.sendMessage(Collections.singletonList(pc.factory().buildKeepaliveMsg().build()));
+        }
+    }
+
+    @Override
+    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
+        if (e.getMessage() instanceof List) {
+            @SuppressWarnings("unchecked")
+            List<PcepMessage> msglist = (List<PcepMessage>) e.getMessage();
+            for (PcepMessage pm : msglist) {
+                // Do the actual packet processing
+                state.processPcepMessage(this, pm);
+            }
+        } else {
+            state.processPcepMessage(this, (PcepMessage) e.getMessage());
+        }
+    }
+
+    /**
+     * Is this a state in which the handshake has completed.
+     *
+     * @return true if the handshake is complete
+     */
+    public boolean isHandshakeComplete() {
+        return this.state.isHandshakeComplete();
+    }
+
+    /**
+     * To set the handshake status.
+     *
+     * @param handshakeComplete value is handshake status
+     */
+    public void setHandshakeComplete(boolean handshakeComplete) {
+        this.state.setHandshakeComplete(handshakeComplete);
+    }
+
+    /**
+     * To handle the pcep message.
+     *
+     * @param m pcep message
+     */
+    private void dispatchMessage(PcepMessage m) {
+        pc.handleMessage(m);
+    }
+
+    /**
+     * Adds PCEP device configuration with capabilities once session is established.
+     */
+    private void addNode() {
+        pc.addNode(pc);
+    }
+
+    /**
+     * Deletes PCEP device configuration when session is disconnected.
+     */
+    private void deleteNode() {
+        pc.deleteNode(pc.getPccId());
+    }
+
+    /**
+     * Return a string describing this client based on the already available
+     * information (ip address and/or remote socket).
+     *
+     * @return display string
+     */
+    private String getClientInfoString() {
+        if (pc != null) {
+            return pc.toString();
+        }
+        String channelString;
+        if (channel == null || channel.getRemoteAddress() == null) {
+            channelString = "?";
+        } else {
+            channelString = channel.getRemoteAddress().toString();
+        }
+        String pccIpString;
+        // TODO : implement functionality to get pcc id string
+        pccIpString = "?";
+        return String.format("[%s PCCIP[%s]]", channelString, pccIpString);
+    }
+
+    /**
+     * Update the channels state. Only called from the state machine.
+     *
+     * @param state
+     */
+    private void setState(ChannelState state) {
+        this.state = state;
+    }
+
+    /**
+     * Send handshake open message.
+     *
+     * @throws IOException,PcepParseException
+     */
+    private void sendHandshakeOpenMessage() throws IOException, PcepParseException {
+        PcepOpenObject pcepOpenobj = factory1.buildOpenObject()
+                .setSessionId(sessionId)
+                .setKeepAliveTime(keepAliveTime)
+                .setDeadTime(deadTime)
+                .build();
+        PcepMessage msg = factory1.buildOpenMsg()
+                .setPcepOpenObj(pcepOpenobj)
+                .build();
+        log.debug("Sending OPEN message to {}", channel.getRemoteAddress());
+        channel.write(Collections.singletonList(msg));
+    }
+
+    //Capability negotiation
+    private void capabilityNegotiation(PcepOpenMsg pOpenmsg) {
+        LinkedList<PcepValueType> tlvList = pOpenmsg.getPcepOpenObject().getOptionalTlv();
+        boolean pceccCapability = false;
+        boolean statefulPceCapability = false;
+        boolean pcInstantiationCapability = false;
+        boolean labelStackCapability = false;
+        boolean srCapability = false;
+
+        ListIterator<PcepValueType> listIterator = tlvList.listIterator();
+        while (listIterator.hasNext()) {
+            PcepValueType tlv = listIterator.next();
+
+            switch (tlv.getType()) {
+                case PceccCapabilityTlv.TYPE:
+                    pceccCapability = true;
+                    if (((PceccCapabilityTlv) tlv).sBit()) {
+                        labelStackCapability = true;
+                    }
+                    break;
+                case StatefulPceCapabilityTlv.TYPE:
+                    statefulPceCapability = true;
+                    StatefulPceCapabilityTlv stetefulPcCapTlv = (StatefulPceCapabilityTlv) tlv;
+                    if (stetefulPcCapTlv.getIFlag()) {
+                        pcInstantiationCapability = true;
+                    }
+                    break;
+                case SrPceCapabilityTlv.TYPE:
+                    srCapability = true;
+                    break;
+                default:
+                    continue;
+            }
+        }
+        this.capability = new ClientCapability(pceccCapability, statefulPceCapability, pcInstantiationCapability,
+                labelStackCapability, srCapability);
+    }
+
+    /**
+     * Send keep alive message.
+     *
+     * @throws IOException        when channel is disconnected
+     * @throws PcepParseException while building keep alive message
+     */
+    private void sendKeepAliveMessage() throws IOException, PcepParseException {
+        PcepMessage msg = factory1.buildKeepaliveMsg().build();
+        log.debug("Sending KEEPALIVE message to {}", channel.getRemoteAddress());
+        channel.write(Collections.singletonList(msg));
+    }
+
+    /**
+     * Send error message and close channel with pcc.
+     */
+    private void sendErrMsgAndCloseChannel() {
+        // TODO send error message
+        //Remove PCEP device from topology
+        deleteNode();
+        channel.close();
+    }
+
+    /**
+     * Send error message when an invalid message is received.
+     *
+     * @throws PcepParseException while building error message
+     */
+    private void sendErrMsgForInvalidMsg() throws PcepParseException {
+        byte errorType = 0x02;
+        byte errorValue = 0x00;
+        PcepErrorMsg errMsg = getErrorMsg(errorType, errorValue);
+        channel.write(Collections.singletonList(errMsg));
+    }
+
+    /**
+     * Builds pcep error message based on error value and error type.
+     *
+     * @param errorType  pcep error type
+     * @param errorValue pcep error value
+     * @return pcep error message
+     * @throws PcepParseException while bulding error message
+     */
+    public PcepErrorMsg getErrorMsg(byte errorType, byte errorValue) throws PcepParseException {
+        LinkedList<PcepErrorObject> llerrObj = new LinkedList<>();
+        PcepErrorMsg errMsg;
+
+        PcepErrorObject errObj = factory1.buildPcepErrorObject()
+                .setErrorValue(errorValue)
+                .setErrorType(errorType)
+                .build();
+
+        llerrObj.add(errObj);
+
+        //If Error caught in other than Openmessage
+        LinkedList<PcepError> llPcepErr = new LinkedList<>();
+
+        PcepError pcepErr = factory1.buildPcepError()
+                .setErrorObjList(llerrObj)
+                .build();
+
+        llPcepErr.add(pcepErr);
+
+        PcepErrorInfo errInfo = factory1.buildPcepErrorInfo()
+                .setPcepErrorList(llPcepErr)
+                .build();
+
+        errMsg = factory1.buildPcepErrorMsg()
+                .setPcepErrorInfo(errInfo)
+                .build();
+        return errMsg;
+    }
+
+    /**
+     * Process unknown pcep message received.
+     *
+     * @throws PcepParseException while building pcep error message
+     */
+    public void processUnknownMsg() throws PcepParseException {
+        Date now = null;
+        if (pcepPacketStats.wrongPacketCount() == 0) {
+            now = new Date();
+            pcepPacketStats.setTime(now.getTime());
+            pcepPacketStats.addWrongPacket();
+            sendErrMsgForInvalidMsg();
+        }
+
+        if (pcepPacketStats.wrongPacketCount() > 1) {
+            Date lastest = new Date();
+            pcepPacketStats.addWrongPacket();
+            //converting to seconds
+            if (((lastest.getTime() - pcepPacketStats.getTime()) / 1000) > 60) {
+                now = lastest;
+                pcepPacketStats.setTime(now.getTime());
+                pcepPacketStats.resetWrongPacket();
+                pcepPacketStats.addWrongPacket();
+            } else if (((int) (lastest.getTime() - now.getTime()) / 1000) < 60) {
+                if (MAX_WRONG_COUNT_PACKET <= pcepPacketStats.wrongPacketCount()) {
+                    //reset once wrong packet count reaches MAX_WRONG_COUNT_PACKET
+                    pcepPacketStats.resetWrongPacket();
+                    // max wrong packets received send error message and close the session
+                    sendErrMsgAndCloseChannel();
+                }
+            }
+        }
+    }
+
+    /**
+     * The state machine for handling the client/channel state. All state
+     * transitions should happen from within the state machine (and not from other
+     * parts of the code)
+     */
+    enum ChannelState {
+        /**
+         * Initial state before channel is connected.
+         */
+        INIT(false) {
+
+        },
+        /**
+         * Once the session is established, wait for open message.
+         */
+        OPENWAIT(false) {
+            @Override
+            void processPcepMessage(PcepChannelHandler h, PcepMessage m) throws IOException, PcepParseException {
+
+                log.info("Message received in OPEN WAIT State");
+
+                //check for open message
+                if (m.getType() != PcepType.OPEN) {
+                    // When the message type is not open message increment the wrong packet statistics
+                    h.processUnknownMsg();
+                    log.debug("Message is not OPEN message");
+                } else {
+
+                    h.pcepPacketStats.addInPacket();
+                    PcepOpenMsg pOpenmsg = (PcepOpenMsg) m;
+                    //Do Capability negotiation.
+                    h.capabilityNegotiation(pOpenmsg);
+                    log.debug("Sending handshake OPEN message");
+                    h.sessionId = pOpenmsg.getPcepOpenObject().getSessionId();
+                    h.pcepVersion = pOpenmsg.getPcepOpenObject().getVersion();
+
+                    //setting keepalive and deadTimer
+                    byte yKeepalive = pOpenmsg.getPcepOpenObject().getKeepAliveTime();
+                    byte yDeadTimer = pOpenmsg.getPcepOpenObject().getDeadTime();
+                    h.keepAliveTime = yKeepalive;
+                    if (yKeepalive < yDeadTimer) {
+                        h.deadTime = yDeadTimer;
+                    } else {
+                        if (DEADTIMER_MAXIMUM_VALUE > (yKeepalive * KEEPALIVE_MULTIPLE_FOR_DEADTIMER)) {
+                            h.deadTime = (byte) (yKeepalive * KEEPALIVE_MULTIPLE_FOR_DEADTIMER);
+                        } else {
+                            h.deadTime = DEADTIMER_MAXIMUM_VALUE;
+                        }
+                    }
+
+                        /*
+                         * If MPLS LSR id and PCEP session socket IP addresses are not same,
+                         * the MPLS LSR id will be encoded in separate TLV.
+                         * We always maintain session information based on LSR ids.
+                         * The socket IP is stored in channel.
+                         */
+                    LinkedList<PcepValueType> optionalTlvs = pOpenmsg.getPcepOpenObject().getOptionalTlv();
+                    if (optionalTlvs != null) {
+                        for (PcepValueType optionalTlv : optionalTlvs) {
+                            if (optionalTlv instanceof NodeAttributesTlv) {
+                                List<PcepValueType> subTlvs = ((NodeAttributesTlv) optionalTlv)
+                                        .getllNodeAttributesSubTLVs();
+                                if (subTlvs == null) {
+                                    break;
+                                }
+                                for (PcepValueType subTlv : subTlvs) {
+                                    if (subTlv instanceof IPv4RouterIdOfLocalNodeSubTlv) {
+                                        h.thispccId = PccId.pccId(IpAddress
+                                                .valueOf(((IPv4RouterIdOfLocalNodeSubTlv) subTlv).getInt()));
+                                        break;
+                                    }
+                                }
+                                break;
+                            }
+                        }
+                    }
+
+                    if (h.thispccId == null) {
+                        final SocketAddress address = h.channel.getRemoteAddress();
+                        if (!(address instanceof InetSocketAddress)) {
+                            throw new IOException("Invalid client connection. Pcc is indentifed based on IP");
+                        }
+
+                        final InetSocketAddress inetAddress = (InetSocketAddress) address;
+                        h.thispccId = PccId.pccId(IpAddress.valueOf(inetAddress.getAddress()));
+                    }
+
+                    h.sendHandshakeOpenMessage();
+                    h.pcepPacketStats.addOutPacket();
+                    h.setState(KEEPWAIT);
+                    h.controller.peerStatus(h.peerAddr.toString(), PcepCfg.State.KEEPWAIT.toString(), h.sessionId);
+                }
+            }
+        },
+        /**
+         * Once the open messages are exchanged, wait for keep alive message.
+         */
+        KEEPWAIT(false) {
+            @Override
+            void processPcepMessage(PcepChannelHandler h, PcepMessage m) throws IOException, PcepParseException {
+                log.info("Message received in KEEPWAIT state");
+                //check for keep alive message
+                if (m.getType() != PcepType.KEEP_ALIVE) {
+                    // When the message type is not keep alive message increment the wrong packet statistics
+                    h.processUnknownMsg();
+                    log.error("Message is not KEEPALIVE message");
+                } else {
+                    // Set the client connected status
+                    h.pcepPacketStats.addInPacket();
+                    log.debug("sending keep alive message in KEEPWAIT state");
+                    h.pc = h.controller.getPcepClientInstance(h.thispccId, h.sessionId, h.pcepVersion,
+                            h.pcepPacketStats);
+                    //Get pc instance and set capabilities
+                    h.pc.setCapability(h.capability);
+
+                    // Initilialize DB sync status.
+                    h.pc.setLspDbSyncStatus(NOT_SYNCED);
+                    h.pc.setLabelDbSyncStatus(NOT_SYNCED);
+
+                    // set the status of pcc as connected
+                    h.pc.setConnected(true);
+                    h.pc.setChannel(h.channel);
+
+                    // set any other specific parameters to the pcc
+                    h.pc.setPcVersion(h.pcepVersion);
+                    h.pc.setPcSessionId(h.sessionId);
+                    h.pc.setPcKeepAliveTime(h.keepAliveTime);
+                    h.pc.setPcDeadTime(h.deadTime);
+                    int keepAliveTimer = h.keepAliveTime & BYTE_MASK;
+                    int deadTimer = h.deadTime & BYTE_MASK;
+                    if (0 == h.keepAliveTime) {
+                        h.deadTime = 0;
+                    }
+                    // handle keep alive and dead time
+                    if (keepAliveTimer != PcepPipelineFactory.DEFAULT_KEEP_ALIVE_TIME
+                            || deadTimer != PcepPipelineFactory.DEFAULT_DEAD_TIME) {
+
+                        h.channel.getPipeline().replace("idle", "idle",
+                                new IdleStateHandler(PcepPipelineFactory.TIMER, deadTimer, keepAliveTimer, 0));
+                    }
+                    log.debug("Dead timer : " + deadTimer);
+                    log.debug("Keep alive time : " + keepAliveTimer);
+
+                    //set the state handshake completion.
+
+                    h.sendKeepAliveMessage();
+                    h.pcepPacketStats.addOutPacket();
+                    h.setHandshakeComplete(true);
+
+                    if (!h.pc.connectClient()) {
+                        disconnectDuplicate(h);
+                    } else {
+                        h.setState(ESTABLISHED);
+                     h.controller.peerStatus(h.peerAddr.toString(), PcepCfg.State.ESTABLISHED.toString(), h.sessionId);
+                        //Session is established, add a network configuration with LSR id and device capabilities.
+                        h.addNode();
+                    }
+                }
+            }
+        },
+        /**
+         * Once the keep alive messages are exchanged, the state is established.
+         */
+        ESTABLISHED(true) {
+            @Override
+            void processPcepMessage(PcepChannelHandler h, PcepMessage m) throws IOException, PcepParseException {
+
+                //h.channel.getPipeline().remove("waittimeout");
+                log.debug("Message received in established state " + m.getType());
+                //dispatch the message
+                h.dispatchMessage(m);
+            }
+        };
+        private boolean handshakeComplete;
+
+        ChannelState(boolean handshakeComplete) {
+            this.handshakeComplete = handshakeComplete;
+        }
+
+        void processPcepMessage(PcepChannelHandler h, PcepMessage m) throws IOException, PcepParseException {
+            // do nothing
+        }
+
+        /**
+         * Is this a state in which the handshake has completed.
+         *
+         * @return true if the handshake is complete
+         */
+        public boolean isHandshakeComplete() {
+            return this.handshakeComplete;
+        }
+
+        /**
+         * Sets handshake complete status.
+         *
+         * @param handshakeComplete status of handshake
+         */
+        public void setHandshakeComplete(boolean handshakeComplete) {
+            this.handshakeComplete = handshakeComplete;
+        }
+
+        protected void disconnectDuplicate(PcepChannelHandler h) {
+            log.error("Duplicated Pcc IP or incompleted cleanup - " + "disconnecting channel {}",
+                    h.getClientInfoString());
+            h.duplicatePccIdFound = Boolean.TRUE;
+            h.channel.disconnect();
+        }
+
+    }
+}
diff --git a/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/PcepClientControllerImpl.java b/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/PcepClientControllerImpl.java
new file mode 100644
index 0000000..2ddc819
--- /dev/null
+++ b/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/PcepClientControllerImpl.java
@@ -0,0 +1,1230 @@
+/*
+ * Copyright 2015-present Open Networking Foundation
+ *
+ * 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.pcep.server.impl;
+
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.List;
+import java.util.LinkedList;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.HashMap;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.ListIterator;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
+import org.onosproject.incubator.net.resource.label.LabelResourceAdminService;
+import org.onosproject.incubator.net.resource.label.LabelResourceId;
+import org.onosproject.incubator.net.resource.label.LabelResourceService;
+import org.onosproject.incubator.net.tunnel.DefaultLabelStack;
+import org.onosproject.incubator.net.tunnel.DefaultTunnel;
+import org.onosproject.incubator.net.tunnel.IpTunnelEndPoint;
+import org.onosproject.incubator.net.tunnel.LabelStack;
+import org.onosproject.incubator.net.tunnel.Tunnel;
+import org.onosproject.incubator.net.tunnel.TunnelService;
+import org.onosproject.incubator.net.tunnel.Tunnel.State;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultAnnotations.Builder;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.MastershipRole;
+import org.onosproject.net.Path;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.config.NetworkConfigService;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.link.LinkEvent;
+import org.onosproject.net.link.LinkListener;
+import org.onosproject.net.link.LinkService;
+import org.onosproject.pcelabelstore.PcepLabelOp;
+import org.onosproject.pcelabelstore.api.PceLabelStore;
+import org.onosproject.pcep.api.DeviceCapability;
+import org.onosproject.pcep.server.LspKey;
+import org.onosproject.pcep.server.LspType;
+import org.onosproject.pcep.server.PccId;
+import org.onosproject.pcep.server.PcepClient;
+import org.onosproject.pcep.server.PcepClientController;
+import org.onosproject.pcep.server.PcepClientListener;
+import org.onosproject.pcep.server.PcepEventListener;
+import org.onosproject.pcep.server.PcepLspStatus;
+import org.onosproject.pcep.server.PcepNodeListener;
+import org.onosproject.pcep.server.SrpIdGenerators;
+import org.onosproject.pcep.server.driver.PcepAgent;
+import org.onosproject.pcepio.exceptions.PcepParseException;
+import org.onosproject.pcepio.protocol.PcInitiatedLspRequest;
+import org.onosproject.pcepio.protocol.PcepError;
+import org.onosproject.pcepio.protocol.PcepErrorInfo;
+import org.onosproject.pcepio.protocol.PcepErrorMsg;
+import org.onosproject.pcepio.protocol.PcepErrorObject;
+import org.onosproject.pcepio.protocol.PcepFactory;
+import org.onosproject.pcepio.protocol.PcepInitiateMsg;
+import org.onosproject.pcepio.protocol.PcepLspObject;
+import org.onosproject.pcepio.protocol.PcepMessage;
+import org.onosproject.pcepio.protocol.PcepNai;
+import org.onosproject.pcepio.protocol.PcepReportMsg;
+import org.onosproject.pcepio.protocol.PcepSrpObject;
+import org.onosproject.pcepio.protocol.PcepStateReport;
+import org.onosproject.pcepio.types.PathSetupTypeTlv;
+import org.onosproject.pcepio.types.PcepNaiIpv4Adjacency;
+import org.onosproject.pcepio.types.PcepNaiIpv4NodeId;
+import org.onosproject.pcepio.types.PcepValueType;
+import org.onosproject.pcepio.types.SrEroSubObject;
+import org.onosproject.pcepio.types.StatefulIPv4LspIdentifiersTlv;
+import org.onosproject.pcepio.types.SymbolicPathNameTlv;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Sets;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import static org.onosproject.pcep.server.PcepSyncStatus.IN_SYNC;
+import static org.onosproject.pcep.server.LspType.WITHOUT_SIGNALLING_AND_WITHOUT_SR;
+import static org.onosproject.pcep.server.LspType.WITH_SIGNALLING;
+import static org.onosproject.pcep.server.PcepLspSyncAction.REMOVE;
+import static org.onosproject.pcep.server.PcepLspSyncAction.SEND_UPDATE;
+import static org.onosproject.pcep.server.PcepLspSyncAction.UNSTABLE;
+import static org.onosproject.pcepio.types.PcepErrorDetailInfo.ERROR_TYPE_19;
+import static org.onosproject.pcepio.types.PcepErrorDetailInfo.ERROR_VALUE_5;
+import static org.onosproject.pcep.server.PcepAnnotationKeys.BANDWIDTH;
+import static org.onosproject.pcep.server.PcepAnnotationKeys.LOCAL_LSP_ID;
+import static org.onosproject.pcep.server.PcepAnnotationKeys.LSP_SIG_TYPE;
+import static org.onosproject.pcep.server.PcepAnnotationKeys.PCC_TUNNEL_ID;
+import static org.onosproject.pcep.server.PcepAnnotationKeys.PCE_INIT;
+import static org.onosproject.pcep.server.PcepAnnotationKeys.PLSP_ID;
+import static org.onosproject.pcep.server.PcepAnnotationKeys.DELEGATE;
+import static org.onosproject.pcep.server.PcepAnnotationKeys.COST_TYPE;
+import static org.onosproject.pcep.server.PcepSyncStatus.SYNCED;
+import static org.onosproject.pcep.server.PcepSyncStatus.NOT_SYNCED;
+
+/**
+ * Implementation of PCEP client controller.
+ */
+@Component(immediate = true)
+@Service
+public class PcepClientControllerImpl implements PcepClientController {
+
+    private static final Logger log = LoggerFactory.getLogger(PcepClientControllerImpl.class);
+    private static final long IDENTIFIER_SET = 0x100000000L;
+    private static final long SET = 0xFFFFFFFFL;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected LinkService linkService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected TunnelService tunnelService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigService netCfgService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected MastershipService mastershipService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected LabelResourceAdminService labelRsrcAdminService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected LabelResourceService labelRsrcService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected PceLabelStore pceStore;
+
+    protected ConcurrentHashMap<PccId, PcepClient> connectedClients =
+            new ConcurrentHashMap<>();
+
+    protected PcepClientAgent agent = new PcepClientAgent();
+    protected Set<PcepClientListener> pcepClientListener = new HashSet<>();
+
+    protected Set<PcepEventListener> pcepEventListener = Sets.newHashSet();
+    protected Set<PcepNodeListener> pcepNodeListener = Sets.newHashSet();
+
+    // LSR-id and device-id mapping for checking capability if L3 device is not
+    // having its capability
+    private Map<String, DeviceId> lsrIdDeviceIdMap = new HashMap<>();
+
+    private final Controller ctrl = new Controller();
+    public static final long GLOBAL_LABEL_SPACE_MIN = 4097;
+    public static final long GLOBAL_LABEL_SPACE_MAX = 5121;
+    private static final String LSRID = "lsrId";
+    private static final String DEVICE_NULL = "Device-cannot be null";
+    private static final String LINK_NULL = "Link-cannot be null";
+
+    private BasicPceccHandler crHandler;
+    private PceccSrTeBeHandler srTeHandler;
+
+    private DeviceListener deviceListener = new InternalDeviceListener();
+    private LinkListener linkListener = new InternalLinkListener();
+    private InternalConfigListener cfgListener = new InternalConfigListener();
+    private Map<Integer, Integer> pcepErrorMsg = new TreeMap<>();
+
+    @Activate
+    public void activate() {
+        ctrl.start(agent);
+        crHandler = BasicPceccHandler.getInstance();
+        crHandler.initialize(labelRsrcService, deviceService, pceStore, this);
+
+        srTeHandler = PceccSrTeBeHandler.getInstance();
+        srTeHandler.initialize(labelRsrcAdminService, labelRsrcService, this, pceStore,
+                               deviceService);
+
+        deviceService.addListener(deviceListener);
+        linkService.addListener(linkListener);
+        netCfgService.addListener(cfgListener);
+
+        // Reserve global node pool
+        if (!srTeHandler.reserveGlobalPool(GLOBAL_LABEL_SPACE_MIN, GLOBAL_LABEL_SPACE_MAX)) {
+            log.debug("Global node pool was already reserved.");
+        }
+
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        // Close all connected clients
+        closeConnectedClients();
+        deviceService.removeListener(deviceListener);
+        linkService.removeListener(linkListener);
+        netCfgService.removeListener(cfgListener);
+        ctrl.stop();
+        log.info("Stopped");
+    }
+
+    @Override
+    public void peerErrorMsg(String peerId, Integer errorType, Integer errValue) {
+        if (peerId == null) {
+            pcepErrorMsg.put(errorType, errValue);
+        } else {
+            if (pcepErrorMsg.size() > 10) {
+                pcepErrorMsg.clear();
+            }
+            pcepErrorMsg.put(errorType, errValue);
+        }
+    }
+
+    @Override
+    public Map<String, List<String>> getPcepExceptions() {
+        return this.ctrl.exceptionsMap();
+    }
+
+    @Override
+    public Map<Integer, Integer> getPcepErrorMsg() {
+        return pcepErrorMsg;
+    }
+
+
+    @Override
+    public Map<String, String> getPcepSessionMap() {
+        return this.ctrl.mapPeer();
+    }
+
+    @Override
+    public Map<String, Byte> getPcepSessionIdMap() {
+        return this.ctrl.mapSession();
+    }
+
+    @Override
+    public Collection<PcepClient> getClients() {
+        return connectedClients.values();
+    }
+
+    @Override
+    public PcepClient getClient(PccId pccId) {
+        return connectedClients.get(pccId);
+    }
+
+    @Override
+    public void addListener(PcepClientListener listener) {
+        if (!pcepClientListener.contains(listener)) {
+            this.pcepClientListener.add(listener);
+        }
+    }
+
+    @Override
+    public void removeListener(PcepClientListener listener) {
+        this.pcepClientListener.remove(listener);
+    }
+
+    @Override
+    public void addEventListener(PcepEventListener listener) {
+        pcepEventListener.add(listener);
+    }
+
+    @Override
+    public void removeEventListener(PcepEventListener listener) {
+        pcepEventListener.remove(listener);
+    }
+
+    @Override
+    public void writeMessage(PccId pccId, PcepMessage msg) {
+        this.getClient(pccId).sendMessage(msg);
+    }
+
+    @Override
+    public void addNodeListener(PcepNodeListener listener) {
+        pcepNodeListener.add(listener);
+    }
+
+    @Override
+    public void removeNodeListener(PcepNodeListener listener) {
+        pcepNodeListener.remove(listener);
+    }
+
+    @Override
+    public void processClientMessage(PccId pccId, PcepMessage msg) {
+        PcepClient pc = getClient(pccId);
+
+        switch (msg.getType()) {
+        case NONE:
+            break;
+        case OPEN:
+            break;
+        case KEEP_ALIVE:
+            break;
+        case PATH_COMPUTATION_REQUEST:
+            break;
+        case PATH_COMPUTATION_REPLY:
+            break;
+        case NOTIFICATION:
+            break;
+        case ERROR:
+            break;
+        case INITIATE:
+            if (!pc.capability().pcInstantiationCapability()) {
+                pc.sendMessage(Collections.singletonList(getErrMsg(pc.factory(), ERROR_TYPE_19,
+                        ERROR_VALUE_5)));
+            }
+            break;
+        case UPDATE:
+            if (!pc.capability().statefulPceCapability()) {
+                pc.sendMessage(Collections.singletonList(getErrMsg(pc.factory(), ERROR_TYPE_19,
+                        ERROR_VALUE_5)));
+            }
+            break;
+        case LABEL_UPDATE:
+            if (!pc.capability().pceccCapability()) {
+                pc.sendMessage(Collections.singletonList(getErrMsg(pc.factory(), ERROR_TYPE_19,
+                        ERROR_VALUE_5)));
+            }
+            break;
+        case CLOSE:
+            log.info("Sending Close Message  to {" + pccId.toString() + "}");
+            pc.sendMessage(Collections.singletonList(pc.factory().buildCloseMsg().build()));
+            //now disconnect client
+            pc.disconnectClient();
+            break;
+        case REPORT:
+            //Only update the listener if respective capability is supported else send PCEP-ERR msg
+            if (pc.capability().statefulPceCapability()) {
+
+                ListIterator<PcepStateReport> listIterator = ((PcepReportMsg) msg).getStateReportList().listIterator();
+                while (listIterator.hasNext()) {
+                    PcepStateReport stateRpt = listIterator.next();
+                    PcepLspObject lspObj = stateRpt.getLspObject();
+                    if (lspObj.getSFlag()) {
+                        if (pc.lspDbSyncStatus() != IN_SYNC) {
+                            log.debug("LSP DB sync started for PCC {}", pc.getPccId().id().toString());
+                            // Initialize LSP DB sync and temporary cache.
+                            pc.setLspDbSyncStatus(IN_SYNC);
+                            pc.initializeSyncMsgList(pccId);
+                        }
+                        // Store stateRpt in temporary cache.
+                        pc.addSyncMsgToList(pccId, stateRpt);
+
+                        // Don't send to provider as of now.
+                        continue;
+                    } else if (lspObj.getPlspId() == 0) {
+                        if (pc.lspDbSyncStatus() == IN_SYNC
+                                || pc.lspDbSyncStatus() == NOT_SYNCED) {
+                            // Set end of LSPDB sync.
+                            log.debug("LSP DB sync completed for PCC {}", pc.getPccId().id().toString());
+                            pc.setLspDbSyncStatus(SYNCED);
+
+                            // Call packet provider to initiate label DB sync (only if PCECC capable).
+                            if (pc.capability().pceccCapability()) {
+                                log.debug("Trigger label DB sync for PCC {}", pc.getPccId().id().toString());
+                                pc.setLabelDbSyncStatus(IN_SYNC);
+                                // Get lsrId of the PCEP client from the PCC ID. Session info is based on lsrID.
+                                String lsrId = String.valueOf(pccId.ipAddress());
+                                DeviceId pccDeviceId = DeviceId.deviceId(lsrId);
+                                try {
+                                    syncLabelDb(pccDeviceId);
+                                    pc.setLabelDbSyncStatus(SYNCED);
+                                } catch (PcepParseException e) {
+                                    log.error("Exception caught in sending label masg to PCC while in sync.");
+                                }
+                            } else {
+                                // If label db sync is not to be done, handle end of LSPDB sync actions.
+                                agent.analyzeSyncMsgList(pccId);
+                            }
+                            continue;
+                        }
+                    }
+
+                    PcepLspStatus pcepLspStatus = PcepLspStatus.values()[lspObj.getOFlag()];
+                    LspType lspType = getLspType(stateRpt.getSrpObject());
+
+                    // Download (or remove) labels for basic PCECC LSPs.
+                    if (lspType.equals(WITHOUT_SIGNALLING_AND_WITHOUT_SR)) {
+                        boolean isRemove = lspObj.getRFlag();
+                        Tunnel tunnel = null;
+
+                        if (isRemove || pcepLspStatus.equals(PcepLspStatus.GOING_UP)) {
+                            tunnel = getTunnel(lspObj);
+                        }
+
+                        if (tunnel != null) {
+                            if (isRemove) {
+                                crHandler.releaseLabel(tunnel);
+                            } else {
+                                crHandler.allocateLabel(tunnel);
+                            }
+                        }
+                    }
+
+                    // It's a usual report message while sync is not undergoing. So process it immediately.
+                    LinkedList<PcepStateReport> llPcRptList = new LinkedList<>();
+                    llPcRptList.add(stateRpt);
+                    PcepMessage pcReportMsg = pc.factory().buildReportMsg().setStateReportList((llPcRptList))
+                            .build();
+                    for (PcepEventListener l : pcepEventListener) {
+                        l.handleMessage(pccId, pcReportMsg);
+                    }
+                }
+            } else {
+                // Send PCEP-ERROR message.
+                pc.sendMessage(Collections.singletonList(getErrMsg(pc.factory(),
+                        ERROR_TYPE_19, ERROR_VALUE_5)));
+            }
+            break;
+        case LABEL_RANGE_RESERV:
+            break;
+        case LS_REPORT: //TODO: need to handle LS report to add or remove node
+            break;
+        case MAX:
+            break;
+        case END:
+            break;
+        default:
+            break;
+        }
+    }
+
+    private LspType getLspType(PcepSrpObject srpObj) {
+        LspType lspType = WITH_SIGNALLING;
+
+        if (null != srpObj) {
+            LinkedList<PcepValueType> llOptionalTlv = srpObj.getOptionalTlv();
+            ListIterator<PcepValueType> listIterator = llOptionalTlv.listIterator();
+
+            while (listIterator.hasNext()) {
+                PcepValueType tlv = listIterator.next();
+                switch (tlv.getType()) {
+                case PathSetupTypeTlv.TYPE:
+                    lspType = LspType.values()[Integer.valueOf(((PathSetupTypeTlv) tlv).getPst())];
+                    break;
+                default:
+                    break;
+                }
+            }
+        }
+        return lspType;
+    }
+
+    private Tunnel getTunnel(PcepLspObject lspObj) {
+        ListIterator<PcepValueType> listTlvIterator = lspObj.getOptionalTlv().listIterator();
+        StatefulIPv4LspIdentifiersTlv ipv4LspIdenTlv = null;
+        SymbolicPathNameTlv pathNameTlv = null;
+        Tunnel tunnel = null;
+        while (listTlvIterator.hasNext()) {
+            PcepValueType tlv = listTlvIterator.next();
+            switch (tlv.getType()) {
+            case StatefulIPv4LspIdentifiersTlv.TYPE:
+                ipv4LspIdenTlv = (StatefulIPv4LspIdentifiersTlv) tlv;
+                break;
+            case SymbolicPathNameTlv.TYPE:
+                pathNameTlv = (SymbolicPathNameTlv) tlv;
+                break;
+            default:
+                break;
+            }
+        }
+        /*
+         * Draft says: The LSP-IDENTIFIERS TLV MUST be included in the LSP object in PCRpt messages for
+         * RSVP-signaled LSPs. For ONOS PCECC implementation, it is mandatory.
+         */
+        if (ipv4LspIdenTlv == null) {
+            log.error("Stateful IPv4 identifier TLV is null in PCRpt msg.");
+            return null;
+        }
+        IpTunnelEndPoint tunnelEndPointSrc = IpTunnelEndPoint
+                .ipTunnelPoint(IpAddress.valueOf(ipv4LspIdenTlv.getIpv4IngressAddress()));
+        IpTunnelEndPoint tunnelEndPointDst = IpTunnelEndPoint
+                .ipTunnelPoint(IpAddress.valueOf(ipv4LspIdenTlv.getIpv4EgressAddress()));
+        Collection<Tunnel> tunnelQueryResult = tunnelService.queryTunnel(tunnelEndPointSrc, tunnelEndPointDst);
+
+        for (Tunnel tunnelObj : tunnelQueryResult) {
+            if (tunnelObj.annotations().value(PLSP_ID) == null) {
+                /*
+                 * PLSP_ID is null while Tunnel is created at PCE and PCInit msg carries it as 0. It is allocated by
+                 * PCC and in that case it becomes the first PCRpt msg from PCC for this LSP, and hence symbolic
+                 * path name must be carried in the PCRpt msg. Draft says: The SYMBOLIC-PATH-NAME TLV "MUST" be
+                 * included in the LSP object in the LSP State Report (PCRpt) message when during a given PCEP
+                 * session an LSP is "first" reported to a PCE.
+                 */
+                if ((pathNameTlv != null)
+                        && Arrays.equals(tunnelObj.tunnelName().value().getBytes(), pathNameTlv.getValue())) {
+                    tunnel = tunnelObj;
+                    break;
+                }
+                continue;
+            }
+            if ((Integer.valueOf(tunnelObj.annotations().value(PLSP_ID)) == lspObj.getPlspId())) {
+                if ((Integer
+                        .valueOf(tunnelObj.annotations().value(LOCAL_LSP_ID)) == ipv4LspIdenTlv.getLspId())) {
+                    tunnel = tunnelObj;
+                    break;
+                }
+            }
+        }
+
+        if (tunnel == null || tunnel.annotations().value(PLSP_ID) != null) {
+            return tunnel;
+        }
+
+        // The returned tunnel is used just for filling values in Label message. So manipulate locally
+        // and return so that to allocate label, we don't need to wait for the tunnel in the "core"
+        // to be updated, as that depends on listener mechanism and there may be timing/multi-threading issues.
+        Builder annotationBuilder = DefaultAnnotations.builder();
+        annotationBuilder.set(BANDWIDTH, tunnel.annotations().value(BANDWIDTH));
+        annotationBuilder.set(COST_TYPE, tunnel.annotations().value(COST_TYPE));
+        annotationBuilder.set(LSP_SIG_TYPE, tunnel.annotations().value(LSP_SIG_TYPE));
+        annotationBuilder.set(PCE_INIT, tunnel.annotations().value(PCE_INIT));
+        annotationBuilder.set(DELEGATE, tunnel.annotations().value(DELEGATE));
+        annotationBuilder.set(PLSP_ID, String.valueOf(lspObj.getPlspId()));
+        annotationBuilder.set(PCC_TUNNEL_ID, String.valueOf(ipv4LspIdenTlv.getTunnelId()));
+        annotationBuilder.set(LOCAL_LSP_ID, tunnel.annotations().value(LOCAL_LSP_ID));
+
+        Tunnel updatedTunnel = new DefaultTunnel(tunnel.providerId(), tunnel.src(),
+                            tunnel.dst(), tunnel.type(),
+                            tunnel.state(), tunnel.groupId(),
+                            tunnel.tunnelId(),
+                            tunnel.tunnelName(),
+                            tunnel.path(),
+                            tunnel.resource(),
+                            annotationBuilder.build());
+
+        return updatedTunnel;
+    }
+
+    @Override
+    public void closeConnectedClients() {
+        PcepClient pc;
+        for (PccId id : connectedClients.keySet()) {
+            pc = getClient(id);
+            pc.disconnectClient();
+        }
+    }
+
+    /**
+     * Returns pcep error message with specific error type and value.
+     *
+     * @param factory represents pcep factory
+     * @param errorType pcep error type
+     * @param errorValue pcep error value
+     * @return pcep error message
+     */
+    public PcepErrorMsg getErrMsg(PcepFactory factory, byte errorType, byte errorValue) {
+        LinkedList<PcepError> llPcepErr = new LinkedList<>();
+
+        LinkedList<PcepErrorObject> llerrObj = new LinkedList<>();
+        PcepErrorMsg errMsg;
+
+        PcepErrorObject errObj = factory.buildPcepErrorObject().setErrorValue(errorValue).setErrorType(errorType)
+                .build();
+
+        llerrObj.add(errObj);
+        PcepError pcepErr = factory.buildPcepError().setErrorObjList(llerrObj).build();
+
+        llPcepErr.add(pcepErr);
+
+        PcepErrorInfo errInfo = factory.buildPcepErrorInfo().setPcepErrorList(llPcepErr).build();
+
+        errMsg = factory.buildPcepErrorMsg().setPcepErrorInfo(errInfo).build();
+        return errMsg;
+    }
+
+    private boolean syncLabelDb(DeviceId deviceId) throws PcepParseException {
+        checkNotNull(deviceId);
+
+        DeviceId actualDevcieId = pceStore.getLsrIdDevice(deviceId.toString());
+        if (actualDevcieId == null) {
+            log.error("Device not available {}.", deviceId.toString());
+            pceStore.addPccLsr(deviceId);
+            return false;
+        }
+        PcepClient pc = connectedClients.get(PccId.pccId(IpAddress.valueOf(deviceId.toString())));
+
+        Device specificDevice = deviceService.getDevice(actualDevcieId);
+        if (specificDevice == null) {
+            log.error("Unable to find device for specific device id {}.", actualDevcieId.toString());
+            return false;
+        }
+
+        if (pceStore.getGlobalNodeLabel(actualDevcieId) != null) {
+            Map<DeviceId, LabelResourceId> globalNodeLabelMap = pceStore.getGlobalNodeLabels();
+
+            for (Entry<DeviceId, LabelResourceId> entry : globalNodeLabelMap.entrySet()) {
+
+                // Convert from DeviceId to TunnelEndPoint
+                Device srcDevice = deviceService.getDevice(entry.getKey());
+
+                /*
+                 * If there is a slight difference in timing such that if device subsystem has removed the device but
+                 * PCE store still has it, just ignore such devices.
+                 */
+                if (srcDevice == null) {
+                    continue;
+                }
+
+                String srcLsrId = srcDevice.annotations().value(LSRID);
+                if (srcLsrId == null) {
+                    continue;
+                }
+
+                srTeHandler.pushGlobalNodeLabel(pc, entry.getValue(),
+                                    IpAddress.valueOf(srcLsrId).getIp4Address().toInt(),
+                                    PcepLabelOp.ADD, false);
+            }
+
+            Map<Link, LabelResourceId> adjLabelMap = pceStore.getAdjLabels();
+            for (Entry<Link, LabelResourceId> entry : adjLabelMap.entrySet()) {
+                if (entry.getKey().src().deviceId().equals(actualDevcieId)) {
+                    srTeHandler.pushAdjacencyLabel(pc,
+                                       entry.getValue(),
+                                       (int) entry.getKey().src().port().toLong(),
+                                       (int) entry.getKey().dst().port().toLong(),
+                                       PcepLabelOp.ADD
+                                       );
+                }
+            }
+        }
+
+        srTeHandler.pushGlobalNodeLabel(pc, LabelResourceId.labelResourceId(0),
+                            0, PcepLabelOp.ADD, true);
+
+        log.debug("End of label DB sync for device {}", actualDevcieId);
+
+        if (mastershipService.getLocalRole(specificDevice.id()) == MastershipRole.MASTER) {
+            // Allocate node-label to this specific device.
+            allocateNodeLabel(specificDevice);
+
+            // Allocate adjacency label
+            Set<Link> links = linkService.getDeviceEgressLinks(specificDevice.id());
+            if (links != null) {
+                for (Link link : links) {
+                    allocateAdjacencyLabel(link);
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Allocates node label to specific device.
+     *
+     * @param specificDevice device to which node label needs to be allocated
+     */
+    public void allocateNodeLabel(Device specificDevice) {
+        checkNotNull(specificDevice, DEVICE_NULL);
+
+        DeviceId deviceId = specificDevice.id();
+
+        // Retrieve lsrId of a specific device
+        if (specificDevice.annotations() == null) {
+            log.debug("Device {} does not have annotations.", specificDevice.toString());
+            return;
+        }
+
+        String lsrId = specificDevice.annotations().value(LSRID);
+        if (lsrId == null) {
+            log.debug("Unable to retrieve lsr-id of a device {}.", specificDevice.toString());
+            return;
+        }
+
+        // Get capability config from netconfig
+        DeviceCapability cfg = netCfgService.getConfig(DeviceId.deviceId(lsrId), DeviceCapability.class);
+        if (cfg == null) {
+            log.error("Unable to find corresponding capability for a lsrd {} from NetConfig.", lsrId);
+            // Save info. When PCEP session is comes up then allocate node-label
+            lsrIdDeviceIdMap.put(lsrId, specificDevice.id());
+            return;
+        }
+
+        // Check whether device has SR-TE Capability
+        if (cfg.labelStackCap()) {
+            srTeHandler.allocateNodeLabel(deviceId, lsrId);
+        }
+    }
+
+    /**
+     * Releases node label of a specific device.
+     *
+     * @param specificDevice this device label and lsr-id information will be
+     *            released in other existing devices
+     */
+    public void releaseNodeLabel(Device specificDevice) {
+        checkNotNull(specificDevice, DEVICE_NULL);
+
+        DeviceId deviceId = specificDevice.id();
+
+        // Retrieve lsrId of a specific device
+        if (specificDevice.annotations() == null) {
+            log.debug("Device {} does not have annotations.", specificDevice.toString());
+            return;
+        }
+
+        String lsrId = specificDevice.annotations().value(LSRID);
+        if (lsrId == null) {
+            log.debug("Unable to retrieve lsr-id of a device {}.", specificDevice.toString());
+            return;
+        }
+
+        // Get capability config from netconfig
+        DeviceCapability cfg = netCfgService.getConfig(DeviceId.deviceId(lsrId), DeviceCapability.class);
+        if (cfg == null) {
+            log.error("Unable to find corresponding capabilty for a lsrd {} from NetConfig.", lsrId);
+            return;
+        }
+
+        // Check whether device has SR-TE Capability
+        if (cfg.labelStackCap()) {
+            if (!srTeHandler.releaseNodeLabel(deviceId, lsrId)) {
+                log.error("Unable to release node label for a device id {}.", deviceId.toString());
+            }
+        }
+    }
+
+    /**
+     * Allocates adjacency label for a link.
+     *
+     * @param link link
+     */
+    public void allocateAdjacencyLabel(Link link) {
+        checkNotNull(link, LINK_NULL);
+
+        Device specificDevice = deviceService.getDevice(link.src().deviceId());
+
+        // Retrieve lsrId of a specific device
+        if (specificDevice.annotations() == null) {
+            log.debug("Device {} does not have annotations.", specificDevice.toString());
+            return;
+        }
+
+        String lsrId = specificDevice.annotations().value(LSRID);
+        if (lsrId == null) {
+            log.debug("Unable to retrieve lsr-id of a device {}.", specificDevice.toString());
+            return;
+        }
+
+        // Get capability config from netconfig
+        DeviceCapability cfg = netCfgService.getConfig(DeviceId.deviceId(lsrId), DeviceCapability.class);
+        if (cfg == null) {
+            log.error("Unable to find corresponding capabilty for a lsrd {} from NetConfig.", lsrId);
+            // Save info. When PCEP session comes up then allocate adjacency
+            // label
+            if (lsrIdDeviceIdMap.get(lsrId) != null) {
+                lsrIdDeviceIdMap.put(lsrId, specificDevice.id());
+            }
+            return;
+        }
+
+        // Check whether device has SR-TE Capability
+        if (cfg.labelStackCap()) {
+            srTeHandler.allocateAdjacencyLabel(link);
+        }
+    }
+
+    /**
+     * Releases allocated adjacency label of a link.
+     *
+     * @param link link
+     */
+    public void releaseAdjacencyLabel(Link link) {
+        checkNotNull(link, LINK_NULL);
+
+        Device specificDevice = deviceService.getDevice(link.src().deviceId());
+
+        // Retrieve lsrId of a specific device
+        if (specificDevice.annotations() == null) {
+            log.debug("Device {} does not have annotations.", specificDevice.toString());
+            return;
+        }
+
+        String lsrId = specificDevice.annotations().value(LSRID);
+        if (lsrId == null) {
+            log.debug("Unable to retrieve lsr-id of a device {}.", specificDevice.toString());
+            return;
+        }
+
+        // Get capability config from netconfig
+        DeviceCapability cfg = netCfgService.getConfig(DeviceId.deviceId(lsrId), DeviceCapability.class);
+        if (cfg == null) {
+            log.error("Unable to find corresponding capabilty for a lsrd {} from NetConfig.", lsrId);
+            return;
+        }
+
+        // Check whether device has SR-TE Capability
+        if (cfg.labelStackCap()) {
+            if (!srTeHandler.releaseAdjacencyLabel(link)) {
+                log.error("Unable to release adjacency labels for a link {}.", link.toString());
+            }
+        }
+    }
+
+    @Override
+    public LabelStack computeLabelStack(Path path) {
+        return srTeHandler.computeLabelStack(path);
+    }
+
+    @Override
+    public boolean allocateLocalLabel(Tunnel tunnel) {
+        return crHandler.allocateLabel(tunnel);
+    }
+
+    /**
+     * Creates label stack for ERO object from network resource.
+     *
+     * @param labelStack label stack
+     * @param path (hop list)
+     * @return list of ERO subobjects
+     */
+    @Override
+    public LinkedList<PcepValueType> createPcepLabelStack(DefaultLabelStack labelStack, Path path) {
+        checkNotNull(labelStack);
+
+        LinkedList<PcepValueType> llSubObjects = new LinkedList<PcepValueType>();
+        Iterator<Link> links = path.links().iterator();
+        LabelResourceId label = null;
+        Link link = null;
+        PcepValueType subObj = null;
+        PcepNai nai = null;
+        Device dstNode = null;
+        long srcPortNo, dstPortNo;
+
+        ListIterator<LabelResourceId> labelListIterator = labelStack.labelResources().listIterator();
+        while (labelListIterator.hasNext()) {
+            label = labelListIterator.next();
+            link = links.next();
+
+            srcPortNo = link.src().port().toLong();
+            srcPortNo = ((srcPortNo & IDENTIFIER_SET) == IDENTIFIER_SET) ? srcPortNo & SET : srcPortNo;
+
+            dstPortNo = link.dst().port().toLong();
+            dstPortNo = ((dstPortNo & IDENTIFIER_SET) == IDENTIFIER_SET) ? dstPortNo & SET : dstPortNo;
+
+            nai = new PcepNaiIpv4Adjacency((int) srcPortNo, (int) dstPortNo);
+            subObj = new SrEroSubObject(PcepNaiIpv4Adjacency.ST_TYPE, false, false, false, true, (int) label.labelId(),
+                                        nai);
+            llSubObjects.add(subObj);
+
+            dstNode = deviceService.getDevice(link.dst().deviceId());
+            nai = new PcepNaiIpv4NodeId(Ip4Address.valueOf(dstNode.annotations().value(LSRID)).toInt());
+
+            if (!labelListIterator.hasNext()) {
+                log.error("Malformed label stack.");
+            }
+            label = labelListIterator.next();
+            subObj = new SrEroSubObject(PcepNaiIpv4NodeId.ST_TYPE, false, false, false, true, (int) label.labelId(),
+                                        nai);
+            llSubObjects.add(subObj);
+        }
+        return llSubObjects;
+    }
+
+    /**
+     * Implementation of an Pcep Agent which is responsible for
+     * keeping track of connected clients and the state in which
+     * they are.
+     */
+    public class PcepClientAgent implements PcepAgent {
+
+        private final Logger log = LoggerFactory.getLogger(PcepClientAgent.class);
+
+        @Override
+        public boolean addConnectedClient(PccId pccId, PcepClient pc) {
+
+            if (connectedClients.get(pccId) != null) {
+                log.error("Trying to add connectedClient but found a previous "
+                        + "value for pcc ip: {}", pccId.toString());
+                return false;
+            } else {
+                log.debug("Added Client {}", pccId.toString());
+                connectedClients.put(pccId, pc);
+                for (PcepClientListener l : pcepClientListener) {
+                    l.clientConnected(pccId);
+                }
+                return true;
+            }
+        }
+
+        @Override
+        public boolean validActivation(PccId pccId) {
+            if (connectedClients.get(pccId) == null) {
+                log.error("Trying to activate client but is not in "
+                        + "connected client: pccIp {}. Aborting ..", pccId.toString());
+                return false;
+            }
+            return true;
+        }
+
+        @Override
+        public void removeConnectedClient(PccId pccId) {
+
+            connectedClients.remove(pccId);
+            for (PcepClientListener l : pcepClientListener) {
+                log.warn("Removal for {}", pccId.toString());
+                l.clientDisconnected(pccId);
+            }
+        }
+
+        @Override
+        public void processPcepMessage(PccId pccId, PcepMessage m) {
+            processClientMessage(pccId, m);
+        }
+
+        @Override
+        public void addNode(PcepClient pc) {
+            for (PcepNodeListener l : pcepNodeListener) {
+                l.addDevicePcepConfig(pc);
+            }
+        }
+
+        @Override
+        public void deleteNode(PccId pccId) {
+            for (PcepNodeListener l : pcepNodeListener) {
+                l.deleteDevicePcepConfig(pccId);
+            }
+        }
+
+        @SuppressWarnings({ "unchecked", "rawtypes" })
+        @Override
+        public boolean analyzeSyncMsgList(PccId pccId) {
+            PcepClient pc = getClient(pccId);
+            /*
+             * PLSP_ID is null while tunnel is created at PCE and PCInit msg carries it as 0. It is allocated by PCC and
+             * in that case it becomes the first PCRpt msg from PCC for this LSP, and hence symbolic path name must be
+             * carried in the PCRpt msg. Draft says: The SYMBOLIC-PATH-NAME TLV "MUST" be included in the LSP object in
+             * the LSP State Report (PCRpt) message when during a given PCEP session an LSP is "first" reported to a
+             * PCE. So two separate lists with separate keys are maintained.
+             */
+            Map<LspKey, Tunnel> preSyncLspDbByKey = new HashMap<>();
+            Map<String, Tunnel> preSyncLspDbByName = new HashMap<>();
+
+            // Query tunnel service and fetch all the tunnels with this PCC as ingress.
+            // Organize into two maps, with LSP key if known otherwise with symbolic path name, for quick search.
+            Collection<Tunnel> queriedTunnels = tunnelService.queryTunnel(Tunnel.Type.MPLS);
+            for (Tunnel tunnel : queriedTunnels) {
+                if (((IpTunnelEndPoint) tunnel.src()).ip().equals(pccId.ipAddress())) {
+                    String pLspId = tunnel.annotations().value(PLSP_ID);
+                    if (pLspId != null) {
+                        String localLspId = tunnel.annotations().value(LOCAL_LSP_ID);
+                        checkNotNull(localLspId);
+                        LspKey lspKey = new LspKey(Integer.valueOf(pLspId), Short.valueOf(localLspId));
+                        preSyncLspDbByKey.put(lspKey, tunnel);
+                    } else {
+                        preSyncLspDbByName.put(tunnel.tunnelName().value(), tunnel);
+                    }
+                }
+            }
+
+            List<PcepStateReport> syncStateRptList = pc.getSyncMsgList(pccId);
+            if (syncStateRptList == null) {
+                // When there are no LSPs to sync, directly end-of-sync PCRpt will come and the
+                // list will be null.
+                syncStateRptList = Collections.EMPTY_LIST;
+                log.debug("No LSPs reported from PCC during sync.");
+            }
+
+            Iterator<PcepStateReport> stateRptListIterator = syncStateRptList.iterator();
+
+            // For every report, fetch PLSP id, local LSP id and symbolic path name from the message.
+            while (stateRptListIterator.hasNext()) {
+                PcepStateReport stateRpt = stateRptListIterator.next();
+                Tunnel tunnel = null;
+
+                PcepLspObject lspObj = stateRpt.getLspObject();
+                ListIterator<PcepValueType> listTlvIterator = lspObj.getOptionalTlv().listIterator();
+                StatefulIPv4LspIdentifiersTlv ipv4LspIdenTlv = null;
+                SymbolicPathNameTlv pathNameTlv = null;
+
+                while (listTlvIterator.hasNext()) {
+                    PcepValueType tlv = listTlvIterator.next();
+                    switch (tlv.getType()) {
+                    case StatefulIPv4LspIdentifiersTlv.TYPE:
+                        ipv4LspIdenTlv = (StatefulIPv4LspIdentifiersTlv) tlv;
+                        break;
+
+                    case SymbolicPathNameTlv.TYPE:
+                        pathNameTlv = (SymbolicPathNameTlv) tlv;
+                        break;
+
+                    default:
+                        break;
+                    }
+                }
+
+                LspKey lspKeyOfRpt = new LspKey(lspObj.getPlspId(), ipv4LspIdenTlv.getLspId());
+                tunnel = preSyncLspDbByKey.get(lspKeyOfRpt);
+                // PCE tunnel is matched with PCRpt LSP. Now delete it from the preSyncLspDb list as the residual
+                // non-matching list will be processed at the end.
+                if (tunnel != null) {
+                    preSyncLspDbByKey.remove(lspKeyOfRpt);
+                } else if (pathNameTlv != null) {
+                    tunnel = preSyncLspDbByName.get(Arrays.toString(pathNameTlv.getValue()));
+                    if (tunnel != null) {
+                        preSyncLspDbByName.remove(tunnel.tunnelName().value());
+                    }
+                }
+
+                if (tunnel == null) {
+                    // If remove flag is set, and tunnel is not known to PCE, ignore it.
+                    if (lspObj.getCFlag() && !lspObj.getRFlag()) {
+                        // For initiated LSP, need to send PCInit delete msg.
+                        try {
+                            PcepSrpObject srpobj = pc.factory().buildSrpObject().setSrpID(SrpIdGenerators.create())
+                                    .setRFlag(true).build();
+                            PcInitiatedLspRequest releaseLspRequest = pc.factory().buildPcInitiatedLspRequest()
+                                    .setLspObject(lspObj).setSrpObject(srpobj).build();
+                            LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList
+                                    = new LinkedList<PcInitiatedLspRequest>();
+                            llPcInitiatedLspRequestList.add(releaseLspRequest);
+
+                            PcepInitiateMsg pcInitiateMsg = pc.factory().buildPcepInitiateMsg()
+                                    .setPcInitiatedLspRequestList(llPcInitiatedLspRequestList).build();
+
+                            pc.sendMessage(Collections.singletonList(pcInitiateMsg));
+                        } catch (PcepParseException e) {
+                            log.error("Exception occured while sending initiate delete message {}", e.getMessage());
+                        }
+                        continue;
+                    }
+                }
+
+                if (!lspObj.getCFlag()) {
+                    // For learned LSP process both add/update PCRpt.
+                    LinkedList<PcepStateReport> llPcRptList = new LinkedList<>();
+                    llPcRptList.add(stateRpt);
+                    PcepMessage pcReportMsg = pc.factory().buildReportMsg().setStateReportList((llPcRptList))
+                            .build();
+
+                    for (PcepEventListener l : pcepEventListener) {
+                        l.handleMessage(pccId, pcReportMsg);
+                    }
+                    continue;
+                }
+
+                // Implied that tunnel != null and lspObj.getCFlag() is set
+                // State different for PCC sent LSP and PCE known LSP, send PCUpd msg.
+                State tunnelState = PcepLspStatus
+                        .getTunnelStatusFromLspStatus(PcepLspStatus.values()[lspObj.getOFlag()]);
+                if (tunnelState != tunnel.state()) {
+                    for (PcepEventListener l : pcepEventListener) {
+                        l.handleEndOfSyncAction(tunnel, SEND_UPDATE);
+                    }
+                }
+            }
+
+            // Check which tunnels are extra at PCE that were not reported by PCC.
+            Map<Object, Tunnel> preSyncLspDb = (Map) preSyncLspDbByKey;
+            handleResidualTunnels(preSyncLspDb);
+            preSyncLspDbByKey = null;
+
+            preSyncLspDb = (Map) preSyncLspDbByName;
+            handleResidualTunnels(preSyncLspDb);
+            preSyncLspDbByName = null;
+            preSyncLspDb = null;
+
+            pc.removeSyncMsgList(pccId);
+            return true;
+        }
+
+        /*
+         * Go through the tunnels which are known by PCE but were not reported by PCC during LSP DB sync and take
+         * appropriate actions.
+         */
+        private void handleResidualTunnels(Map<Object, Tunnel> preSyncLspDb) {
+            for (Tunnel pceExtraTunnel : preSyncLspDb.values()) {
+                if (pceExtraTunnel.annotations().value(PCE_INIT) == null
+                        || "false".equalsIgnoreCase(pceExtraTunnel.annotations().value(PCE_INIT))) {
+                    // PCC initiated tunnels should be removed from tunnel store.
+                    for (PcepEventListener l : pcepEventListener) {
+                        l.handleEndOfSyncAction(pceExtraTunnel, REMOVE);
+                    }
+                } else {
+                    // PCE initiated tunnels should be initiated again.
+                    for (PcepEventListener l : pcepEventListener) {
+                        l.handleEndOfSyncAction(pceExtraTunnel, UNSTABLE);
+                    }
+                }
+            }
+        }
+    }
+
+    /*
+     * Handle device events.
+     */
+    private class InternalDeviceListener implements DeviceListener {
+        @Override
+        public void event(DeviceEvent event) {
+            Device specificDevice = event.subject();
+            if (specificDevice == null) {
+                log.error("Unable to find device from device event.");
+                return;
+            }
+
+            switch (event.type()) {
+
+            case DEVICE_ADDED:
+                // Node-label allocation is being done during Label DB Sync.
+                // So, when device is detected, no need to do node-label
+                // allocation.
+                String lsrId = specificDevice.annotations().value(LSRID);
+                if (lsrId != null) {
+                    pceStore.addLsrIdDevice(lsrId, specificDevice.id());
+
+                    // Search in failed DB sync store. If found, trigger label DB sync.
+                    DeviceId pccDeviceId = DeviceId.deviceId(lsrId);
+                    if (pceStore.hasPccLsr(pccDeviceId)) {
+                        log.debug("Continue to perform label DB sync for device {}.", pccDeviceId.toString());
+                        try {
+                            syncLabelDb(pccDeviceId);
+                        } catch (PcepParseException e) {
+                            log.error("Exception caught in sending label masg to PCC while in sync.");
+                        }
+                        pceStore.removePccLsr(pccDeviceId);
+                    }
+                }
+                break;
+
+            case DEVICE_REMOVED:
+                // Release node-label
+                if (mastershipService.getLocalRole(specificDevice.id()) == MastershipRole.MASTER) {
+                    releaseNodeLabel(specificDevice);
+                }
+
+                if (specificDevice.annotations().value(LSRID) != null) {
+                    pceStore.removeLsrIdDevice(specificDevice.annotations().value(LSRID));
+                }
+                break;
+
+            default:
+                break;
+            }
+        }
+    }
+
+    /*
+     * Handle link events.
+     */
+    private class InternalLinkListener implements LinkListener {
+        @Override
+        public void event(LinkEvent event) {
+            Link link = event.subject();
+
+            switch (event.type()) {
+
+            case LINK_ADDED:
+                // Allocate adjacency label
+                if (mastershipService.getLocalRole(link.src().deviceId()) == MastershipRole.MASTER) {
+                    allocateAdjacencyLabel(link);
+                }
+                break;
+
+            case LINK_REMOVED:
+                // Release adjacency label
+                if (mastershipService.getLocalRole(link.src().deviceId()) == MastershipRole.MASTER) {
+                    releaseAdjacencyLabel(link);
+                }
+                break;
+
+            default:
+                break;
+            }
+        }
+    }
+
+    private class InternalConfigListener implements NetworkConfigListener {
+
+        @Override
+        public void event(NetworkConfigEvent event) {
+
+            if ((event.type() == NetworkConfigEvent.Type.CONFIG_ADDED)
+                    && event.configClass().equals(DeviceCapability.class)) {
+
+                DeviceId deviceIdLsrId = (DeviceId) event.subject();
+                String lsrId = deviceIdLsrId.toString();
+                DeviceId deviceId = lsrIdDeviceIdMap.get(lsrId);
+                if (deviceId == null) {
+                    log.debug("Unable to find device id for a lsr-id {} from lsr-id and device-id map.", lsrId);
+                    return;
+                }
+
+                DeviceCapability cfg = netCfgService.getConfig(DeviceId.deviceId(lsrId), DeviceCapability.class);
+                if (cfg == null) {
+                    log.error("Unable to find corresponding capabilty for a lsrd {}.", lsrId);
+                    return;
+                }
+
+                if (cfg.labelStackCap()) {
+                    if (mastershipService.getLocalRole(deviceId) == MastershipRole.MASTER) {
+                        // Allocate node-label
+                        srTeHandler.allocateNodeLabel(deviceId, lsrId);
+
+                        // Allocate adjacency label to links which are
+                        // originated from this specific device id
+                        Set<Link> links = linkService.getDeviceEgressLinks(deviceId);
+                        for (Link link : links) {
+                            if (!srTeHandler.allocateAdjacencyLabel(link)) {
+                                return;
+                            }
+                        }
+                    }
+                }
+                // Remove lsrId info from map
+                lsrIdDeviceIdMap.remove(lsrId);
+            }
+        }
+    }
+}
diff --git a/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/PcepClientImpl.java b/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/PcepClientImpl.java
new file mode 100644
index 0000000..7e52c19
--- /dev/null
+++ b/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/PcepClientImpl.java
@@ -0,0 +1,303 @@
+/*
+ * Copyright 2015-present Open Networking Foundation
+ *
+ * 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.pcep.server.impl;
+
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.RejectedExecutionException;
+
+import org.jboss.netty.channel.Channel;
+import org.onlab.packet.IpAddress;
+import org.onosproject.pcep.server.ClientCapability;
+import org.onosproject.pcep.server.LspKey;
+import org.onosproject.pcep.server.PccId;
+import org.onosproject.pcep.server.PcepClient;
+import org.onosproject.pcep.server.PcepPacketStats;
+import org.onosproject.pcep.server.PcepSyncStatus;
+import org.onosproject.pcep.server.driver.PcepAgent;
+import org.onosproject.pcep.server.driver.PcepClientDriver;
+import org.onosproject.pcepio.protocol.PcepFactories;
+import org.onosproject.pcepio.protocol.PcepFactory;
+import org.onosproject.pcepio.protocol.PcepMessage;
+import org.onosproject.pcepio.protocol.PcepStateReport;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * An abstract representation of an OpenFlow switch. Can be extended by others
+ * to serve as a base for their vendor specific representation of a switch.
+ */
+public class PcepClientImpl implements PcepClientDriver {
+
+    protected final Logger log = LoggerFactory.getLogger(PcepClientImpl.class);
+
+    private static final String SHUTDOWN_MSG = "Worker has already been shutdown";
+
+    private Channel channel;
+    protected String channelId;
+
+    private boolean connected;
+    protected boolean startDriverHandshakeCalled;
+    protected boolean isHandShakeComplete;
+    private PcepSyncStatus lspDbSyncStatus;
+    private PcepSyncStatus labelDbSyncStatus;
+    private PccId pccId;
+    private PcepAgent agent;
+
+    private ClientCapability capability;
+    private PcepVersion pcepVersion;
+    private byte keepAliveTime;
+    private byte deadTime;
+    private byte sessionId;
+    private PcepPacketStatsImpl pktStats;
+    private Map<LspKey, Boolean> lspDelegationInfo = new HashMap<>();
+    private Map<PccId, List<PcepStateReport>> syncRptCache = new HashMap<>();
+
+    @Override
+    public void init(PccId pccId, PcepVersion pcepVersion, PcepPacketStats pktStats) {
+        this.pccId = pccId;
+        this.pcepVersion = pcepVersion;
+        this.pktStats = (PcepPacketStatsImpl) pktStats;
+    }
+
+    @Override
+    public final void disconnectClient() {
+        this.channel.close();
+    }
+
+    @Override
+    public void setCapability(ClientCapability capability) {
+        this.capability = capability;
+    }
+
+    @Override
+    public ClientCapability capability() {
+        return capability;
+    }
+
+    @Override
+    public final void sendMessage(PcepMessage m) {
+        log.debug("Sending message to {}", channel.getRemoteAddress());
+        try {
+            channel.write(Collections.singletonList(m));
+            this.pktStats.addOutPacket();
+        } catch (RejectedExecutionException e) {
+            log.warn(e.getMessage());
+            if (!e.getMessage().contains(SHUTDOWN_MSG)) {
+                throw e;
+            }
+        }
+    }
+
+    @Override
+    public final void sendMessage(List<PcepMessage> msgs) {
+        try {
+            channel.write(msgs);
+            this.pktStats.addOutPacket(msgs.size());
+        } catch (RejectedExecutionException e) {
+            log.warn(e.getMessage());
+            if (!e.getMessage().contains(SHUTDOWN_MSG)) {
+                throw e;
+            }
+        }
+    }
+
+    @Override
+    public final boolean isConnected() {
+        return this.connected;
+    }
+
+    @Override
+    public final void setConnected(boolean connected) {
+        this.connected = connected;
+    };
+
+    @Override
+    public final void setChannel(Channel channel) {
+        this.channel = channel;
+        final SocketAddress address = channel.getRemoteAddress();
+        if (address instanceof InetSocketAddress) {
+            final InetSocketAddress inetAddress = (InetSocketAddress) address;
+            final IpAddress ipAddress = IpAddress.valueOf(inetAddress.getAddress());
+            if (ipAddress.isIp4()) {
+                channelId = ipAddress.toString() + ':' + inetAddress.getPort();
+            } else {
+                channelId = '[' + ipAddress.toString() + "]:" + inetAddress.getPort();
+            }
+        }
+    };
+
+    @Override
+    public String channelId() {
+        return channelId;
+    }
+
+    @Override
+    public final PccId getPccId() {
+        return this.pccId;
+    }
+
+    @Override
+    public final String getStringId() {
+        return this.pccId.toString();
+    }
+
+    @Override
+    public final void setPcVersion(PcepVersion pcepVersion) {
+        this.pcepVersion = pcepVersion;
+    }
+
+    @Override
+    public void setPcKeepAliveTime(byte keepAliveTime) {
+        this.keepAliveTime = keepAliveTime;
+    }
+
+    @Override
+    public void setPcDeadTime(byte deadTime) {
+        this.deadTime = deadTime;
+    }
+
+    @Override
+    public void setPcSessionId(byte sessionId) {
+        this.sessionId = sessionId;
+    }
+
+    @Override
+    public void setLspDbSyncStatus(PcepSyncStatus syncStatus) {
+        log.debug("LSP DB sync status set from {} to {}", this.lspDbSyncStatus, syncStatus);
+        this.lspDbSyncStatus = syncStatus;
+    }
+
+    @Override
+    public PcepSyncStatus lspDbSyncStatus() {
+        return lspDbSyncStatus;
+    }
+
+    @Override
+    public void setLabelDbSyncStatus(PcepSyncStatus syncStatus) {
+
+        PcepSyncStatus syncOldStatus = labelDbSyncStatus();
+        this.labelDbSyncStatus = syncStatus;
+        log.debug("Label DB sync status set from {} to {}", syncOldStatus, syncStatus);
+        if ((syncOldStatus == PcepSyncStatus.IN_SYNC) && (syncStatus == PcepSyncStatus.SYNCED)) {
+            // Perform end of LSP DB sync actions.
+            this.agent.analyzeSyncMsgList(pccId);
+        }
+    }
+
+    @Override
+    public PcepSyncStatus labelDbSyncStatus() {
+        return labelDbSyncStatus;
+    }
+
+    @Override
+    public final void handleMessage(PcepMessage m) {
+        this.pktStats.addInPacket();
+        this.agent.processPcepMessage(pccId, m);
+    }
+
+    @Override
+    public void addNode(PcepClient pc) {
+        this.agent.addNode(pc);
+    }
+
+    @Override
+    public void deleteNode(PccId pccId) {
+        this.agent.deleteNode(pccId);
+    }
+
+    @Override
+    public final boolean connectClient() {
+        return this.agent.addConnectedClient(pccId, this);
+    }
+
+    @Override
+    public final void removeConnectedClient() {
+        this.agent.removeConnectedClient(pccId);
+    }
+
+    @Override
+    public PcepFactory factory() {
+        return PcepFactories.getFactory(pcepVersion);
+    }
+
+    @Override
+    public boolean isHandshakeComplete() {
+        return isHandShakeComplete;
+    }
+
+    @Override
+    public final void setAgent(PcepAgent ag) {
+        if (this.agent == null) {
+            this.agent = ag;
+        }
+    }
+
+    @Override
+    public void setLspAndDelegationInfo(LspKey lspKey, boolean dFlag) {
+        lspDelegationInfo.put(lspKey, dFlag);
+    }
+
+    @Override
+    public Boolean delegationInfo(LspKey lspKey) {
+        return lspDelegationInfo.get(lspKey);
+    }
+
+    @Override
+    public void initializeSyncMsgList(PccId pccId) {
+        List<PcepStateReport> rptMsgList = new LinkedList<>();
+        syncRptCache.put(pccId, rptMsgList);
+    }
+
+    @Override
+    public List<PcepStateReport> getSyncMsgList(PccId pccId) {
+        return syncRptCache.get(pccId);
+    }
+
+    @Override
+    public void removeSyncMsgList(PccId pccId) {
+        syncRptCache.remove(pccId);
+    }
+
+    @Override
+    public void addSyncMsgToList(PccId pccId, PcepStateReport rptMsg) {
+        List<PcepStateReport> rptMsgList = syncRptCache.get(pccId);
+        rptMsgList.add(rptMsg);
+        syncRptCache.put(pccId, rptMsgList);
+    }
+
+    @Override
+    public boolean isOptical() {
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("channel", channelId())
+                .add("pccId", getPccId())
+                .toString();
+    }
+}
diff --git a/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/PcepConfig.java b/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/PcepConfig.java
new file mode 100644
index 0000000..e6b5fe1
--- /dev/null
+++ b/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/PcepConfig.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * 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.pcep.server.impl;
+
+import org.onosproject.pcep.server.PccId;
+import org.onosproject.pcep.server.PcepCfg;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.TreeMap;
+
+
+public class PcepConfig implements PcepCfg {
+
+    protected static final Logger log = LoggerFactory.getLogger(PcepConfig.class);
+
+    private State state = State.INIT;
+    private PccId pccId;
+    private TreeMap<String, PcepCfg> bgpPeerTree = new TreeMap<>();
+
+    @Override
+    public State getState() {
+        return state;
+    }
+
+    @Override
+    public void setState(State state) {
+        this.state = state;
+    }
+
+}
diff --git a/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/PcepControllerImpl.java b/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/PcepControllerImpl.java
new file mode 100644
index 0000000..8d9bc23
--- /dev/null
+++ b/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/PcepControllerImpl.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * 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.pcep.server.impl;
+
+import com.google.common.collect.Sets;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Service;
+import org.onosproject.net.DeviceId;
+import org.onosproject.pcep.api.PcepController;
+import org.onosproject.pcep.api.PcepDpid;
+import org.onosproject.pcep.api.PcepLinkListener;
+import org.onosproject.pcep.api.PcepSwitch;
+import org.onosproject.pcep.api.PcepSwitchListener;
+import org.onosproject.pcep.api.PcepTunnel;
+import org.onosproject.pcep.api.PcepTunnelListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Set;
+
+/**
+ * Implementation of PCEP controller [protocol].
+ */
+@Component(immediate = true)
+@Service
+public class PcepControllerImpl implements PcepController {
+
+    private static final Logger log = LoggerFactory.getLogger(PcepControllerImpl.class);
+
+    protected Set<PcepTunnelListener> pcepTunnelListener = Sets.newHashSet();
+    protected Set<PcepLinkListener> pcepLinkListener = Sets.newHashSet();
+    protected Set<PcepSwitchListener> pcepSwitchListener = Sets.newHashSet();
+
+    private final Controller ctrl = new Controller();
+
+    @Activate
+    public void activate() {
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        log.info("Stopped");
+    }
+
+    @Override
+    public Iterable<PcepSwitch> getSwitches() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public PcepSwitch getSwitch(PcepDpid did) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void addListener(PcepSwitchListener listener) {
+        this.pcepSwitchListener.add(listener);
+    }
+
+    @Override
+    public void removeListener(PcepSwitchListener listener) {
+        this.pcepSwitchListener.remove(listener);
+    }
+
+    @Override
+    public void addLinkListener(PcepLinkListener listener) {
+        this.pcepLinkListener.add(listener);
+    }
+
+    @Override
+    public void removeLinkListener(PcepLinkListener listener) {
+        this.pcepLinkListener.remove(listener);
+    }
+
+    @Override
+    public void addTunnelListener(PcepTunnelListener listener) {
+        this.pcepTunnelListener.add(listener);
+    }
+
+    @Override
+    public void removeTunnelListener(PcepTunnelListener listener) {
+        this.pcepTunnelListener.remove(listener);
+    }
+
+    @Override
+    public PcepTunnel applyTunnel(DeviceId srcDid, DeviceId dstDid, long srcPort, long dstPort, long bandwidth,
+            String name) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Boolean deleteTunnel(String id) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public Boolean updateTunnelBandwidth(String id, long bandwidth) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public void getTunnelStatistics(String pcepTunnelId) {
+        // TODO Auto-generated method stub
+    }
+}
diff --git a/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/PcepMessageDecoder.java b/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/PcepMessageDecoder.java
new file mode 100644
index 0000000..2c21b73
--- /dev/null
+++ b/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/PcepMessageDecoder.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2015-present Open Networking Foundation
+ *
+ * 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.pcep.server.impl;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.channel.Channel;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.handler.codec.frame.FrameDecoder;
+import org.onosproject.pcepio.exceptions.PcepOutOfBoundMessageException;
+import org.onosproject.pcepio.protocol.PcepFactories;
+import org.onosproject.pcepio.protocol.PcepMessage;
+import org.onosproject.pcepio.protocol.PcepMessageReader;
+import org.onosproject.pcepio.util.HexDump;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Decode an pcep message from a Channel, for use in a netty pipeline.
+ */
+public class PcepMessageDecoder extends FrameDecoder {
+
+    protected static final Logger log = LoggerFactory.getLogger(PcepMessageDecoder.class);
+
+    @Override
+    protected Object decode(ChannelHandlerContext ctx, Channel channel,
+            ChannelBuffer buffer) throws Exception {
+        log.debug("Message received.");
+        if (!channel.isConnected()) {
+            log.info("Channel is not connected.");
+            // In testing, I see decode being called AFTER decode last.
+            // This check avoids that from reading corrupted frames
+            return null;
+        }
+
+        HexDump.pcepHexDump(buffer);
+
+        // Buffer can contain multiple messages, also may contain out of bound message.
+        // Read the message one by one from buffer and parse it. If it encountered out of bound message,
+        // then mark the reader index and again take the next chunk of messages from the channel
+        // and parse again from the marked reader index.
+        PcepMessageReader<PcepMessage> reader = PcepFactories.getGenericReader();
+        List<PcepMessage> msgList = (List<PcepMessage>) ctx.getAttachment();
+
+        if (msgList == null) {
+            msgList = new LinkedList<>();
+        }
+
+        try {
+            while (buffer.readableBytes() > 0) {
+                buffer.markReaderIndex();
+                PcepMessage message = reader.readFrom(buffer);
+                msgList.add(message);
+            }
+            ctx.setAttachment(null);
+            return msgList;
+        } catch (PcepOutOfBoundMessageException e) {
+            log.debug("PCEP message decode error");
+            buffer.resetReaderIndex();
+            buffer.discardReadBytes();
+            ctx.setAttachment(msgList);
+        }
+        return null;
+    }
+}
diff --git a/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/PcepMessageEncoder.java b/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/PcepMessageEncoder.java
new file mode 100644
index 0000000..4c26f88
--- /dev/null
+++ b/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/PcepMessageEncoder.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2015-present Open Networking Foundation
+ *
+ * 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.pcep.server.impl;
+
+import java.util.List;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.buffer.ChannelBuffers;
+import org.jboss.netty.channel.Channel;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.handler.codec.oneone.OneToOneEncoder;
+import org.onosproject.pcepio.protocol.PcepMessage;
+import org.onosproject.pcepio.util.HexDump;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Encode an pcep message for output into a ChannelBuffer, for use in a
+ * netty pipeline.
+ */
+public class PcepMessageEncoder extends OneToOneEncoder {
+    protected static final Logger log = LoggerFactory.getLogger(PcepMessageEncoder.class);
+
+    @Override
+    protected Object encode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception {
+        log.debug("Sending message");
+        if (!(msg instanceof List)) {
+            log.debug("Invalid msg.");
+            return msg;
+        }
+
+        @SuppressWarnings("unchecked")
+        List<PcepMessage> msglist = (List<PcepMessage>) msg;
+
+        ChannelBuffer buf = ChannelBuffers.dynamicBuffer();
+
+        for (PcepMessage pm : msglist) {
+            pm.writeTo(buf);
+        }
+
+        HexDump.pcepHexDump(buf);
+
+        return buf;
+    }
+}
diff --git a/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/PcepPacketStatsImpl.java b/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/PcepPacketStatsImpl.java
new file mode 100644
index 0000000..1659247
--- /dev/null
+++ b/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/PcepPacketStatsImpl.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2015-present Open Networking Foundation
+ *
+ * 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.pcep.server.impl;
+
+import org.onosproject.pcep.server.PcepPacketStats;
+
+/**
+ * The implementation for PCEP packet statistics.
+ */
+public class PcepPacketStatsImpl implements PcepPacketStats {
+
+    private int inPacketCount;
+    private int outPacketCount;
+    private int wrongPacketCount;
+    private long time;
+
+    /**
+     * Default constructor.
+     */
+    public PcepPacketStatsImpl() {
+        this.inPacketCount = 0;
+        this.outPacketCount = 0;
+        this.wrongPacketCount = 0;
+        this.time = 0;
+    }
+
+    @Override
+    public int outPacketCount() {
+        return outPacketCount;
+    }
+
+    @Override
+    public int inPacketCount() {
+        return inPacketCount;
+    }
+
+    @Override
+    public int wrongPacketCount() {
+        return wrongPacketCount;
+    }
+
+    /**
+     * Increments the received packet counter.
+     */
+    public void addInPacket() {
+        this.inPacketCount++;
+    }
+
+    /**
+     * Increments the sent packet counter.
+     */
+    public void addOutPacket() {
+        this.outPacketCount++;
+    }
+
+    /**
+     * Increments the sent packet counter by specified value.
+     *
+     * @param value of no of packets sent
+     */
+    public void addOutPacket(int value) {
+        this.outPacketCount = this.outPacketCount + value;
+    }
+
+    /**
+     * Increments the wrong packet counter.
+     */
+    public void addWrongPacket() {
+        this.wrongPacketCount++;
+    }
+
+    /**
+     * Resets wrong packet count.
+     */
+    public void resetWrongPacket() {
+        this.wrongPacketCount = 0;
+    }
+
+    @Override
+    public long getTime() {
+        return this.time;
+    }
+
+    /**
+     * Sets the time value.
+     *
+     * @param time long value of time
+     */
+    public void setTime(long time) {
+        this.time = time;
+    }
+}
diff --git a/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/PcepPipelineFactory.java b/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/PcepPipelineFactory.java
new file mode 100644
index 0000000..f1932e9
--- /dev/null
+++ b/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/PcepPipelineFactory.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2015-present Open Networking Foundation
+ *
+ * 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.pcep.server.impl;
+
+import org.jboss.netty.channel.ChannelPipeline;
+import org.jboss.netty.channel.ChannelPipelineFactory;
+import org.jboss.netty.channel.Channels;
+import org.jboss.netty.handler.timeout.IdleStateHandler;
+import org.jboss.netty.handler.timeout.ReadTimeoutHandler;
+import org.jboss.netty.util.ExternalResourceReleasable;
+import org.jboss.netty.util.HashedWheelTimer;
+import org.jboss.netty.util.Timer;
+
+/**
+ * Creates a ChannelPipeline for a server-side pcep channel.
+ */
+public class PcepPipelineFactory
+    implements ChannelPipelineFactory, ExternalResourceReleasable {
+
+    protected Controller controller;
+    static final Timer TIMER = new HashedWheelTimer();
+    protected IdleStateHandler idleHandler;
+    protected ReadTimeoutHandler readTimeoutHandler;
+    static final int DEFAULT_KEEP_ALIVE_TIME = 30;
+    static final int DEFAULT_DEAD_TIME = 120;
+    static final int DEFAULT_WAIT_TIME = 60;
+
+    public PcepPipelineFactory(Controller controller) {
+        super();
+        this.controller = controller;
+        this.idleHandler = new IdleStateHandler(TIMER, DEFAULT_DEAD_TIME, DEFAULT_KEEP_ALIVE_TIME, 0);
+        this.readTimeoutHandler = new ReadTimeoutHandler(TIMER, DEFAULT_WAIT_TIME);
+    }
+
+    @Override
+    public ChannelPipeline getPipeline() throws Exception {
+        PcepChannelHandler handler = new PcepChannelHandler(controller);
+
+        ChannelPipeline pipeline = Channels.pipeline();
+        pipeline.addLast("pcepmessagedecoder", new PcepMessageDecoder());
+        pipeline.addLast("pcepmessageencoder", new PcepMessageEncoder());
+        pipeline.addLast("idle", idleHandler);
+        pipeline.addLast("waittimeout", readTimeoutHandler);
+        pipeline.addLast("handler", handler);
+        return pipeline;
+    }
+
+    @Override
+    public void releaseExternalResources() {
+        TIMER.stop();
+    }
+}
diff --git a/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/package-info.java b/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/package-info.java
new file mode 100644
index 0000000..4fd2660
--- /dev/null
+++ b/protocols/pcep/server/ctl/src/main/java/org/onosproject/pcep/server/impl/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2015-present Open Networking Foundation
+ *
+ * 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.
+ */
+
+/**
+ * Implementation of the PCEP client controller subsystem.
+ */
+package org.onosproject.pcep.server.impl;
