diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorInfoVer1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorInfoVer1.java
new file mode 100644
index 0000000..e22f7a9
--- /dev/null
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorInfoVer1.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.pcepio.protocol.ver1;
+
+import java.util.LinkedList;
+import java.util.ListIterator;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.exceptions.PcepParseException;
+import org.onosproject.pcepio.protocol.PcepError;
+import org.onosproject.pcepio.protocol.PcepErrorInfo;
+import org.onosproject.pcepio.protocol.PcepErrorObject;
+import org.onosproject.pcepio.protocol.PcepRPObject;
+import org.onosproject.pcepio.protocol.PcepTEObject;
+import org.onosproject.pcepio.types.PcepObjectHeader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides PCEP Error Info.
+ * Reference :PCEP Extension for Transporting TE Data draft-dhodylee-pce-pcep-te-data-extn-02.
+ */
+public class PcepErrorInfoVer1 implements PcepErrorInfo {
+
+    protected static final Logger log = LoggerFactory.getLogger(PcepErrorInfoVer1.class);
+    //Error list is optional
+    private LinkedList<PcepError> errList;
+
+    /**
+     * Constructor to add PCEP error object to the list.
+     *
+     * @param llRPObjList list of PCEP RP object
+     * @param llTEObjList list of PCEP TE object
+     * @param llErrObjList list of PCEP error object
+     */
+    public PcepErrorInfoVer1(LinkedList<PcepRPObject> llRPObjList, LinkedList<PcepTEObject> llTEObjList,
+            LinkedList<PcepErrorObject> llErrObjList) {
+        this.errList = new LinkedList<PcepError>();
+        if ((null != llErrObjList) && (!llErrObjList.isEmpty())) {
+            this.errList.add(new PcepErrorVer1(llRPObjList, llTEObjList, llErrObjList));
+        }
+    }
+
+    /**
+     * Constructor to initialize error info.
+     *
+     * @param errll linked list or pcep error
+     */
+    public PcepErrorInfoVer1(LinkedList<PcepError> errll) {
+        this.errList = errll;
+    }
+
+    @Override
+    public boolean isErrorInfoPresent() {
+        return (!this.errList.isEmpty()) ? true : false;
+    }
+
+    @Override
+    public void read(ChannelBuffer cb) throws PcepParseException {
+        PcepObjectHeader tempObjHeader;
+
+        while (0 < cb.readableBytes()) {
+            cb.markReaderIndex();
+            tempObjHeader = PcepObjectHeader.read(cb);
+            cb.resetReaderIndex();
+            byte yObjClass = tempObjHeader.getObjClass();
+            if ((yObjClass != PcepRPObjectVer1.RP_OBJ_CLASS) && (yObjClass != PcepTEObjectVer1.TE_OBJ_CLASS)
+                    && (yObjClass != PcepErrorObjectVer1.ERROR_OBJ_CLASS)) {
+                throw new PcepParseException("Unknown Object is present in PCEP-ERROR. Object Class: " + yObjClass);
+            }
+
+            this.errList.add(PcepErrorVer1.read(cb));
+        }
+    }
+
+    @Override
+    public void write(ChannelBuffer cb) throws PcepParseException {
+        //write <error>
+        ListIterator<PcepError> listIterator = errList.listIterator();
+        while (listIterator.hasNext()) {
+            PcepError pcepError = listIterator.next();
+
+            //RP Object list is optional
+            LinkedList<PcepRPObject> llRPObjList = pcepError.getRPObjList();
+            if (llRPObjList != null) {
+                ListIterator<PcepRPObject> rpListIterator = llRPObjList.listIterator();
+                while (rpListIterator.hasNext()) {
+                    rpListIterator.next().write(cb);
+                }
+            }
+
+            //TE Object list is optional
+            LinkedList<PcepTEObject> llTEObjList = pcepError.getTEObjList();
+            if (llTEObjList != null) {
+                ListIterator<PcepTEObject> teListIterator = llTEObjList.listIterator();
+                while (teListIterator.hasNext()) {
+                    teListIterator.next().write(cb);
+                }
+            }
+
+            // <error-obj-list> is mandatory
+            boolean bIsErrorObjListFound = false;
+
+            LinkedList<PcepErrorObject> llErrObjList = pcepError.getErrorObjList();
+            if (llErrObjList != null) {
+                ListIterator<PcepErrorObject> errObjListIterator = llErrObjList.listIterator();
+                while (errObjListIterator.hasNext()) {
+                    errObjListIterator.next().write(cb);
+                    bIsErrorObjListFound = true;
+                }
+            }
+
+            if (!bIsErrorObjListFound) {
+                throw new PcepParseException("<error-obj-list> is mandatory.");
+            }
+        }
+    }
+
+    @Override
+    public LinkedList<Integer> getErrorType() {
+        LinkedList<Integer> errorType = new LinkedList<Integer>();
+        ListIterator<PcepError> listIterator = errList.listIterator();
+        PcepErrorObject errObj;
+        int error;
+        while (listIterator.hasNext()) {
+            PcepError pcepError = listIterator.next();
+            LinkedList<PcepErrorObject> llErrObjList = pcepError.getErrorObjList();
+            if (llErrObjList != null) {
+                ListIterator<PcepErrorObject> errObjListIterator = llErrObjList.listIterator();
+                while (errObjListIterator.hasNext()) {
+                    errObj = errObjListIterator.next();
+                    error = errObj.getErrorType();
+                    errorType.add(error);
+                }
+            }
+        }
+        return errorType;
+    }
+
+    @Override
+    public LinkedList<Integer> getErrorValue() {
+        LinkedList<Integer> errorValue = new LinkedList<Integer>();
+        ListIterator<PcepError> listIterator = errList.listIterator();
+        PcepErrorObject errObj;
+        int error;
+        while (listIterator.hasNext()) {
+            PcepError pcepError = listIterator.next();
+            LinkedList<PcepErrorObject> llErrObjList = pcepError.getErrorObjList();
+            if (llErrObjList != null) {
+                ListIterator<PcepErrorObject> errObjListIterator = llErrObjList.listIterator();
+                while (errObjListIterator.hasNext()) {
+                    errObj = errObjListIterator.next();
+                    error = errObj.getErrorValue();
+                    errorValue.add(error);
+                }
+            }
+        }
+        return errorValue;
+    }
+
+    /**
+     * Builder class for PCEP error info.
+     */
+    public static class Builder implements PcepErrorInfo.Builder {
+        private LinkedList<PcepError> errll;
+
+        @Override
+        public PcepErrorInfo build() {
+            return new PcepErrorInfoVer1(errll);
+        }
+
+        @Override
+        public LinkedList<PcepError> getPcepErrorList() {
+            return this.errll;
+        }
+
+        @Override
+        public Builder setPcepErrorList(LinkedList<PcepError> errll) {
+            this.errll = errll;
+            return this;
+        }
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("ErrorList", errList).toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorMsgVer1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorMsgVer1.java
new file mode 100644
index 0000000..91f63ec
--- /dev/null
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorMsgVer1.java
@@ -0,0 +1,360 @@
+package org.onosproject.pcepio.protocol.ver1;
+
+import java.util.LinkedList;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.exceptions.PcepParseException;
+import org.onosproject.pcepio.protocol.PcepErrorInfo;
+import org.onosproject.pcepio.protocol.PcepErrorMsg;
+import org.onosproject.pcepio.protocol.PcepErrorObject;
+import org.onosproject.pcepio.protocol.PcepMessageReader;
+import org.onosproject.pcepio.protocol.PcepMessageWriter;
+import org.onosproject.pcepio.protocol.PcepOpenObject;
+import org.onosproject.pcepio.protocol.PcepType;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.onosproject.pcepio.types.ErrorObjListWithOpen;
+import org.onosproject.pcepio.types.PcepObjectHeader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
+
+public class PcepErrorMsgVer1 implements PcepErrorMsg {
+
+    /*
+     * PCE Error message format.
+
+       <PCErr Message>                ::= <Common Header>
+                                        ( <error-obj-list> [<Open>] ) | <error>
+                                          [<error-list>]
+
+       <error-obj-list>               ::=<PCEP-ERROR>[<error-obj-list>]
+
+       <error>                        ::=[<request-id-list> | <te-id-list>]
+                                           <error-obj-list>
+
+       <request-id-list>              ::=<RP>[<request-id-list>]
+
+       <te-id-list>                   ::=<TE>[<te-id-list>]
+
+       <error-list>                   ::=<error>[<error-list>]
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(PcepOpenMsgVer1.class);
+    public static final byte PACKET_VERSION = 1;
+    public static final int PACKET_MINIMUM_LENGTH = 12;
+    public static final PcepType MSG_TYPE = PcepType.ERROR;
+
+    //Below either one should be present.
+    private ErrorObjListWithOpen errObjListWithOpen; //optional   ( <error-obj-list> [<Open>] )
+    private PcepErrorInfo errInfo; //optional     <error> [<error-list>]
+
+    public static final PcepErrorMsgVer1.Reader READER = new Reader();
+
+    /**
+     * constructor to initialize variables.
+     */
+    public PcepErrorMsgVer1() {
+        errObjListWithOpen = null;
+        errInfo = null;
+    }
+
+    /**
+     * Constructor to initialize variables.
+     *
+     * @param errObjListWithOpen error-object-list with open object
+     * @param errInfo error information
+     */
+    public PcepErrorMsgVer1(ErrorObjListWithOpen errObjListWithOpen, PcepErrorInfo errInfo) {
+        this.errObjListWithOpen = errObjListWithOpen;
+        this.errInfo = errInfo;
+    }
+
+    public static class Reader implements PcepMessageReader<PcepErrorMsg> {
+
+        ErrorObjListWithOpen errObjListWithOpen;
+        PcepErrorInfo errInfo;
+        PcepObjectHeader tempObjHeader;
+
+        @Override
+        public PcepErrorMsg readFrom(ChannelBuffer cb) throws PcepParseException {
+
+            errObjListWithOpen = null;
+            errInfo = null;
+            tempObjHeader = null;
+
+            if (cb.readableBytes() < PACKET_MINIMUM_LENGTH) {
+                throw new PcepParseException("Packet size is less than the minimum length.");
+            }
+
+            byte version = cb.readByte();
+            version = (byte) (version >> PcepMessageVer1.SHIFT_FLAG);
+            if (version != PACKET_VERSION) {
+                throw new PcepParseException("Wrong version: Expected=PcepVersion.PCEP_1(1), got=" + version);
+            }
+            // fixed value property type == 1
+            byte type = cb.readByte();
+            if (type != MSG_TYPE.getType()) {
+                throw new PcepParseException("Wrong type: Expected=PcepType.ERROR(6), got=" + type);
+            }
+            int length = cb.readShort();
+            if (length < PACKET_MINIMUM_LENGTH) {
+                throw new PcepParseException(
+                        "Wrong length: Expected to be >= " + PACKET_MINIMUM_LENGTH + ", was: " + length);
+            }
+
+            //parse <PCErr Message>
+            parsePCErrMsg(cb);
+
+            // If other than RP or TE or PCEP-ERROR present then it is error.
+            if (0 < cb.readableBytes()) {
+                PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
+                throw new PcepParseException("Unexpected Object found. Object Class : " + tempObjHeader.getObjClass());
+            }
+
+            return new PcepErrorMsgVer1(errObjListWithOpen, errInfo);
+        }
+
+        /**
+         * Parsing PCErr Message.
+         *
+         * @param cb channel buffer.
+         * @throws PcepParseException if mandatory fields are missing
+         * output: this.errObjListWithOpen, this.errInfo
+         */
+        public void parsePCErrMsg(ChannelBuffer cb) throws PcepParseException {
+            //If PCEP-ERROR list is followed by OPEN Object then store into ErrorObjListWithOpen.
+            //     ( <error-obj-list> [<Open>]
+            //If PCEP-ERROR list is followed by RP or TE Object then store into errInfo. <error> [<error-list>]
+            //If only PCEP-ERROR list is present then store into ErrorObjListWithOpen.
+            PcepObjectHeader tempObjHeader;
+            LinkedList<PcepErrorObject> llErrObjList;
+
+            if (0 >= cb.readableBytes()) {
+                throw new PcepParseException("PCEP-ERROR message came with empty objects.");
+            }
+
+            //parse PCEP-ERROR list
+            llErrObjList = new LinkedList<PcepErrorObject>();
+            tempObjHeader = parseErrorObjectList(llErrObjList, cb);
+
+            //check whether OPEN-OBJECT is present.
+            if ((tempObjHeader instanceof PcepObjectHeader)
+                    && (tempObjHeader.getObjClass() == PcepOpenObjectVer1.OPEN_OBJ_CLASS)) {
+
+                if (llErrObjList.isEmpty()) {
+                    throw new PcepParseException("<error-obj-list> should be present if OPEN-OBJECT exists");
+                }
+
+                PcepOpenObject pcepOpenObj = PcepOpenObjectVer1.read(cb);
+                this.errObjListWithOpen = new ErrorObjListWithOpen(llErrObjList, pcepOpenObj);
+
+            } else if ((tempObjHeader instanceof PcepObjectHeader) //check whether RP or TE Object is present.
+                    && ((tempObjHeader.getObjClass() == PcepRPObjectVer1.RP_OBJ_CLASS)
+                            || (tempObjHeader.getObjClass() == PcepTEObjectVer1.TE_OBJ_CLASS))) {
+
+                this.errInfo = new PcepErrorInfoVer1(null, null, llErrObjList);
+                this.errInfo.read(cb);
+
+            } else if ((null != llErrObjList) && (!llErrObjList.isEmpty())) {
+                //If only PCEP-ERROR list is present then store it in errObjListWithOpen.
+                this.errObjListWithOpen = new ErrorObjListWithOpen(llErrObjList);
+            } else {
+                throw new PcepParseException("Empty PCEP-ERROR message.");
+            }
+        }
+
+        /**
+         * Parse error-obj-list.
+         *
+         * @param llErrObjList error object list output
+         * @param cb channel buffer input
+         * @throws PcepParseException if mandatory fields are missing
+         * @return error object header
+         */
+        public PcepObjectHeader parseErrorObjectList(LinkedList<PcepErrorObject> llErrObjList, ChannelBuffer cb)
+                throws PcepParseException {
+            PcepObjectHeader tempObjHeader = null;
+
+            while (0 < cb.readableBytes()) {
+                cb.markReaderIndex();
+                tempObjHeader = PcepObjectHeader.read(cb);
+                cb.resetReaderIndex();
+                if (tempObjHeader.getObjClass() == PcepErrorObjectVer1.ERROR_OBJ_CLASS) {
+                    llErrObjList.add(PcepErrorObjectVer1.read(cb));
+                } else {
+                    break;
+                }
+            }
+
+            return tempObjHeader;
+        }
+    }
+
+    /**
+     * Builder class for PCEP error message.
+     */
+    public static class Builder implements PcepErrorMsg.Builder {
+        // Pcep error message fields
+
+        private ErrorObjListWithOpen errObjListWithOpen = null; //optional   ( <error-obj-list> [<Open>] )
+        private PcepErrorInfo errInfo = null; //optional     <error> [<error-list>]
+
+        @Override
+        public PcepVersion getVersion() {
+            return PcepVersion.PCEP_1;
+        }
+
+        @Override
+        public PcepType getType() {
+            return PcepType.ERROR;
+        }
+
+        @Override
+        public PcepErrorMsg build() {
+            return new PcepErrorMsgVer1(this.errObjListWithOpen, this.errInfo);
+        }
+
+        @Override
+        public ErrorObjListWithOpen getErrorObjListWithOpen() {
+            return this.errObjListWithOpen;
+        }
+
+        @Override
+        public Builder setErrorObjListWithOpen(ErrorObjListWithOpen errObjListWithOpen) {
+            this.errObjListWithOpen = errObjListWithOpen;
+            return this;
+        }
+
+        @Override
+        public PcepErrorInfo getPcepErrorInfo() {
+            return this.errInfo;
+        }
+
+        @Override
+        public Builder setPcepErrorInfo(PcepErrorInfo errInfo) {
+            this.errInfo = errInfo;
+            return this;
+        }
+    }
+
+    @Override
+    public void writeTo(ChannelBuffer cb) throws PcepParseException {
+        WRITER.write(cb, this);
+    }
+
+    public static final Writer WRITER = new Writer();
+
+    static class Writer implements PcepMessageWriter<PcepErrorMsgVer1> {
+        @Override
+        public void write(ChannelBuffer cb, PcepErrorMsgVer1 message) throws PcepParseException {
+            int startIndex = cb.writerIndex();
+            // first 3 bits set to version
+            cb.writeByte((byte) (PACKET_VERSION << PcepMessageVer1.SHIFT_FLAG));
+            // message type 0xC
+            cb.writeByte(MSG_TYPE.getType());
+            // length is length of variable message, will be updated at the end
+            // Store the position of message
+            // length in buffer
+            int msgLenIndex = cb.writerIndex();
+            cb.writeShort(0);
+            ErrorObjListWithOpen errObjListWithOpen = message.getErrorObjListWithOpen();
+            PcepErrorInfo errInfo = message.getPcepErrorInfo();
+
+            // write ( <error-obj-list> [<Open>] ) if exists.
+            // otherwise write <error> [<error-list>]
+
+            if ((errObjListWithOpen instanceof ErrorObjListWithOpen)
+                    && (errObjListWithOpen.isErrorObjListWithOpenPresent())) {
+                errObjListWithOpen.write(cb);
+            } else if ((errInfo instanceof PcepErrorInfo) && (errInfo.isErrorInfoPresent())) {
+                errInfo.write(cb);
+            } else {
+                throw new PcepParseException("Empty PCEP-ERROR message.");
+            }
+            // PcepErrorMessage message length field
+            int length = cb.writerIndex() - startIndex;
+            cb.setShort(msgLenIndex, (short) length);
+        }
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public PcepType getType() {
+        return MSG_TYPE;
+    }
+
+    @Override
+    public ErrorObjListWithOpen getErrorObjListWithOpen() {
+        return this.errObjListWithOpen;
+    }
+
+    @Override
+    public void setErrorObjListWithOpen(ErrorObjListWithOpen errObjListWithOpen) {
+        this.errObjListWithOpen = errObjListWithOpen;
+    }
+
+    @Override
+    public PcepErrorInfo getPcepErrorInfo() {
+        return this.errInfo;
+    }
+
+    @Override
+    public void setPcepErrorInfo(PcepErrorInfo errInfo) {
+        this.errInfo = errInfo;
+    }
+
+    /**
+     * Return list of Error types.
+     *
+     * @return error types list
+     */
+    public LinkedList<Integer> getErrorType() {
+        LinkedList<Integer> llErrorType = new LinkedList<Integer>();
+        if ((errObjListWithOpen instanceof ErrorObjListWithOpen)
+                && (errObjListWithOpen.isErrorObjListWithOpenPresent())) {
+            llErrorType = errObjListWithOpen.getErrorType();
+        } else if ((errInfo instanceof PcepErrorInfo) && (errInfo.isErrorInfoPresent())) {
+            llErrorType = errInfo.getErrorType();
+        }
+
+        return llErrorType;
+    }
+
+    /**
+     * Return list of Error values.
+     *
+     * @return error value list
+     */
+    public LinkedList<Integer> getErrorValue() {
+        LinkedList<Integer> llErrorValue = new LinkedList<Integer>();
+        if ((errObjListWithOpen instanceof ErrorObjListWithOpen)
+                && (errObjListWithOpen.isErrorObjListWithOpenPresent())) {
+            llErrorValue = errObjListWithOpen.getErrorValue();
+        } else if ((errInfo instanceof PcepErrorInfo) && (errInfo.isErrorInfoPresent())) {
+            llErrorValue = errInfo.getErrorValue();
+        }
+
+        return llErrorValue;
+    }
+
+    @Override
+    public String toString() {
+        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
+
+        if ((errObjListWithOpen instanceof ErrorObjListWithOpen)
+                && (errObjListWithOpen.isErrorObjListWithOpenPresent())) {
+            toStrHelper.add("ErrorObjectListWithOpen", errObjListWithOpen);
+        }
+        if ((errInfo instanceof PcepErrorInfo) && (errInfo.isErrorInfoPresent())) {
+            toStrHelper.add("ErrorInfo", errInfo);
+        }
+
+        return toStrHelper.toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorObjectVer1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorObjectVer1.java
new file mode 100644
index 0000000..598bfe0
--- /dev/null
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorObjectVer1.java
@@ -0,0 +1,323 @@
+package org.onosproject.pcepio.protocol.ver1;
+
+import java.util.LinkedList;
+import java.util.ListIterator;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.exceptions.PcepParseException;
+import org.onosproject.pcepio.protocol.PcepErrorObject;
+import org.onosproject.pcepio.types.PcepObjectHeader;
+import org.onosproject.pcepio.types.PcepValueType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/*
+0                   1                   2                   3
+0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+| Object-Class  |   OT  |Res|P|I|   Object Length (bytes)       |
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+|   Reserved    |      Flags    |   Error-Type  |  Error-value  |
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+|                                                               |
+//                     Optional TLVs                           //
+|                                                               |
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+public class PcepErrorObjectVer1 implements PcepErrorObject {
+
+    protected static final Logger log = LoggerFactory.getLogger(PcepErrorObjectVer1.class);
+
+    public static final byte ERROR_OBJ_TYPE = 1;
+    public static final byte ERROR_OBJ_CLASS = 13;
+    public static final byte ERROR_OBJECT_VERSION = 1;
+    //ERROR_OBJ_MINIMUM_LENGTH = CommonHeaderLen(4)+ErrorObjectHeaderLen(4)
+    public static final short ERROR_OBJ_MINIMUM_LENGTH = 8;
+    public static final int OBJECT_HEADER_LENGTH = 4;
+
+    public static final PcepObjectHeader DEFAULT_ERROR_OBJECT_HEADER = new PcepObjectHeader(ERROR_OBJ_CLASS,
+            ERROR_OBJ_TYPE, PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED,
+            ERROR_OBJ_MINIMUM_LENGTH);
+
+    private PcepObjectHeader errorObjHeader;
+    private byte yErrorType;
+    private byte yErrorValue;
+    private LinkedList<PcepValueType> llOptionalTlv; // Optional TLV
+
+    /**
+     * Constructor to initialize variables.
+     *
+     * @param errorObjHeader ERROR Object header
+     * @param yErrorType Error Type
+     * @param yErrorValue Error Value
+     * @param llOptionalTlv list of optional TLV
+     */
+
+    public PcepErrorObjectVer1(PcepObjectHeader errorObjHeader, byte yErrorType, byte yErrorValue,
+            LinkedList<PcepValueType> llOptionalTlv) {
+        this.errorObjHeader = errorObjHeader;
+        this.yErrorType = yErrorType;
+        this.yErrorValue = yErrorValue;
+        this.llOptionalTlv = llOptionalTlv;
+    }
+
+    /**
+     * sets Object Header.
+     *
+     * @param obj Error-Object header
+     */
+    public void setLspObjHeader(PcepObjectHeader obj) {
+        this.errorObjHeader = obj;
+    }
+
+    @Override
+    public void setErrorType(byte yErrorType) {
+        this.yErrorType = yErrorType;
+    }
+
+    @Override
+    public void setErrorValue(byte yErrorValue) {
+        this.yErrorValue = yErrorValue;
+    }
+
+    /**
+     * returns object header.
+     *
+     * @return errorObjHeader Error-Object header
+     */
+    public PcepObjectHeader getErrorObjHeader() {
+        return this.errorObjHeader;
+    }
+
+    @Override
+    public int getErrorType() {
+        return this.yErrorType;
+    }
+
+    @Override
+    public byte getErrorValue() {
+        return this.yErrorValue;
+    }
+
+    @Override
+    public LinkedList<PcepValueType> getOptionalTlv() {
+        return this.llOptionalTlv;
+    }
+
+    @Override
+    public void setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
+        this.llOptionalTlv = llOptionalTlv;
+    }
+
+    /**
+     * Reads from channel buffer and returns object of PcepErrorObject.
+     *
+     * @param cb of channel buffer.
+     * @return object of PCEP-ERROR-OBJECT
+     */
+    public static PcepErrorObject read(ChannelBuffer cb) {
+
+        PcepObjectHeader errorObjHeader;
+        byte yErrorType;
+        byte yErrorValue;
+        LinkedList<PcepValueType> llOptionalTlv;
+
+        errorObjHeader = PcepObjectHeader.read(cb);
+
+        //take only ErrorObject buffer.
+        ChannelBuffer tempCb = cb.readBytes(errorObjHeader.getObjLen() - OBJECT_HEADER_LENGTH);
+        tempCb.readByte(); //ignore Reserved
+        tempCb.readByte(); //ignore Flags
+        yErrorType = tempCb.readByte();
+        yErrorValue = tempCb.readByte();
+
+        llOptionalTlv = parseOptionalTlv(tempCb);
+
+        return new PcepErrorObjectVer1(errorObjHeader, yErrorType, yErrorValue, llOptionalTlv);
+    }
+
+    /**
+     * returns Linked list of optional tlvs.
+     *
+     * @param cb channel buffer.
+     * @return Linked list of optional tlvs
+     */
+    protected static LinkedList<PcepValueType> parseOptionalTlv(ChannelBuffer cb) {
+
+        LinkedList<PcepValueType> llOutOptionalTlv = new LinkedList<PcepValueType>();
+
+        byte[] yTemp = new byte[cb.readableBytes()];
+        cb.readBytes(yTemp);
+
+        return llOutOptionalTlv;
+    }
+
+    @Override
+    public int write(ChannelBuffer cb) throws PcepParseException {
+
+        //write Object header
+        int objStartIndex = cb.writerIndex();
+
+        int objLenIndex = errorObjHeader.write(cb);
+
+        if (objLenIndex <= 0) {
+            throw new PcepParseException("While writing Error Object Header.");
+        }
+
+        //write Reserved
+        cb.writeByte(0);
+        //write Flags
+        cb.writeByte(0);
+        //write ErrorType and ErrorValue
+        cb.writeByte(this.yErrorType);
+        cb.writeByte(this.yErrorValue);
+
+        // Add optional TLV
+        packOptionalTlv(cb);
+
+        //Update object length now
+        int length = cb.writerIndex() - objStartIndex;
+        //will be helpful during print().
+        errorObjHeader.setObjLen((short) length);
+        // As per RFC the length of object should be
+        // multiples of 4
+        int pad = length % 4;
+        if (pad != 0) {
+            pad = 4 - pad;
+            for (int i = 0; i < pad; i++) {
+                cb.writeByte((byte) 0);
+            }
+            length = length + pad;
+        }
+
+        cb.setShort(objLenIndex, (short) length);
+        return length;
+    }
+
+    /**
+     * Pack the Optional tlvs.
+     *
+     * @param cb channel buffer.
+     * @return writer index.
+     */
+    protected int packOptionalTlv(ChannelBuffer cb) {
+
+        ListIterator<PcepValueType> listIterator = llOptionalTlv.listIterator();
+        int startIndex = cb.writerIndex();
+        while (listIterator.hasNext()) {
+            PcepValueType tlv = listIterator.next();
+
+            if (null == tlv) {
+                log.debug("TLV is null from OptionalTlv list");
+                continue;
+            }
+            tlv.write(cb);
+        }
+
+        return cb.writerIndex() - startIndex;
+    }
+
+    /**
+     * Builder class for PCEP error object.
+     */
+    public static class Builder implements PcepErrorObject.Builder {
+
+        private boolean bIsHeaderSet = false;
+
+        private PcepObjectHeader errorObjHeader;
+        private byte yErrorType;
+        private byte yErrorValue;
+
+        private boolean bIsPFlagSet = false;
+        private boolean bPFlag;
+
+        private boolean bIsIFlagSet = false;
+        private boolean bIFlag;
+
+        private LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();
+
+        @Override
+        public PcepErrorObject build() {
+
+            PcepObjectHeader errorObjHeader = this.bIsHeaderSet ? this.errorObjHeader : DEFAULT_ERROR_OBJECT_HEADER;
+
+            if (bIsPFlagSet) {
+                errorObjHeader.setPFlag(bPFlag);
+            }
+
+            if (bIsIFlagSet) {
+                errorObjHeader.setIFlag(bIFlag);
+            }
+
+            return new PcepErrorObjectVer1(errorObjHeader, yErrorType, yErrorValue, llOptionalTlv);
+        }
+
+        @Override
+        public PcepObjectHeader getErrorObjHeader() {
+            return this.errorObjHeader;
+        }
+
+        @Override
+        public Builder setErrorObjHeader(PcepObjectHeader obj) {
+            this.errorObjHeader = obj;
+            this.bIsHeaderSet = true;
+            return this;
+        }
+
+        @Override
+        public int getErrorType() {
+            return this.yErrorType;
+        }
+
+        @Override
+        public Builder setErrorType(byte value) {
+            this.yErrorType = value;
+            return this;
+        }
+
+        @Override
+        public byte getErrorValue() {
+            return this.yErrorValue;
+        }
+
+        @Override
+        public Builder setErrorValue(byte value) {
+            this.yErrorValue = value;
+            return this;
+        }
+
+        @Override
+        public Builder setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
+            this.llOptionalTlv = llOptionalTlv;
+            return this;
+        }
+
+        @Override
+        public LinkedList<PcepValueType> getOptionalTlv() {
+            return this.llOptionalTlv;
+        }
+
+        @Override
+        public Builder setPFlag(boolean value) {
+            this.bPFlag = value;
+            this.bIsPFlagSet = true;
+            return this;
+        }
+
+        @Override
+        public Builder setIFlag(boolean value) {
+            this.bIFlag = value;
+            this.bIsIFlagSet = true;
+            return this;
+        }
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("ObjectHeader", errorObjHeader).add("ErrorType", yErrorType)
+                .add("ErrorValue", yErrorValue).add("OptionalTlv", llOptionalTlv).toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorVer1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorVer1.java
new file mode 100644
index 0000000..73c4dff
--- /dev/null
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorVer1.java
@@ -0,0 +1,408 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.pcepio.protocol.ver1;
+
+import java.util.LinkedList;
+import java.util.ListIterator;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.exceptions.PcepParseException;
+import org.onosproject.pcepio.protocol.PcepError;
+import org.onosproject.pcepio.protocol.PcepErrorObject;
+import org.onosproject.pcepio.protocol.PcepRPObject;
+import org.onosproject.pcepio.protocol.PcepTEObject;
+import org.onosproject.pcepio.types.PcepObjectHeader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
+
+/**
+ * Provides PcepError list which contains RP or TE objects.
+ * Reference:PCEP Extension for Transporting TE Data draft-dhodylee-pce-pcep-te-data-extn-02.
+ */
+public class PcepErrorVer1 implements PcepError {
+
+    /*
+           <error>::=[<request-id-list> | <te-id-list>]
+                      <error-obj-list>
+
+           <request-id-list>::=<RP>[<request-id-list>]
+
+           <te-id-list>::=<TE>[<te-id-list>]
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(PcepErrorVer1.class);
+
+    private boolean isErroInfoSet;
+    //PcepErrorObject list
+    private LinkedList<PcepErrorObject> llErrObjList;
+    //PcepRPObject list
+    private LinkedList<PcepRPObject> llRPObjList;
+    //PcepTEObject list
+    private LinkedList<PcepTEObject> llTEObjList;
+    private boolean isTEObjListSet;
+
+    public static final int OBJECT_HEADER_LENGTH = 4;
+
+    /**
+     * Constructor to initialize variable.
+     */
+    public PcepErrorVer1() {
+        this.llRPObjList = null;
+        this.llTEObjList = null;
+        this.llErrObjList = null;
+    }
+
+    /**
+     * Constructor to initialize variable.
+     *
+     * @param llRPObjList list of PcepRPObject
+     * @param llTEObjList list of PcepTEObject
+     * @param llErrObjListObjList list of PcepErrorObject
+     */
+    public PcepErrorVer1(LinkedList<PcepRPObject> llRPObjList, LinkedList<PcepTEObject> llTEObjList,
+            LinkedList<PcepErrorObject> llErrObjListObjList) {
+        this.llRPObjList = llRPObjList;
+        this.llTEObjList = llTEObjList;
+        this.llErrObjList = llErrObjListObjList;
+    }
+
+    /**
+     * Constructor to initialize PcepError.
+     *
+     * @param llErrObjList list of PcepErrorObject
+     */
+    public PcepErrorVer1(LinkedList<PcepErrorObject> llErrObjList) {
+        this.llRPObjList = null;
+        this.llTEObjList = null;
+        this.llErrObjList = llErrObjList;
+    }
+
+    @Override
+    public LinkedList<PcepRPObject> getRPObjList() {
+        return this.llRPObjList;
+    }
+
+    @Override
+    public LinkedList<PcepTEObject> getTEObjList() {
+        return this.llTEObjList;
+    }
+
+    @Override
+    public LinkedList<PcepErrorObject> getErrorObjList() {
+        return this.llErrObjList;
+    }
+
+    /**
+     * Parse RP List from the channel buffer.
+     *
+     * @throws PcepParseException if mandatory fields are missing
+     * @param cb of type channel buffer
+     */
+    public void parseRPList(ChannelBuffer cb) throws PcepParseException {
+        byte yObjClass;
+        byte yObjType;
+
+        llRPObjList = new LinkedList<PcepRPObject>();
+
+        // caller should verify for RP object
+        if (cb.readableBytes() < OBJECT_HEADER_LENGTH) {
+            log.debug("Unable to find RP Object");
+            return;
+        }
+
+        cb.markReaderIndex();
+        PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
+        cb.resetReaderIndex();
+        yObjClass = tempObjHeader.getObjClass();
+        yObjType = tempObjHeader.getObjType();
+        PcepRPObject rpObj;
+        while ((yObjClass == PcepRPObjectVer1.RP_OBJ_CLASS) && (yObjType == PcepRPObjectVer1.RP_OBJ_TYPE)) {
+            rpObj = PcepRPObjectVer1.read(cb);
+            llRPObjList.add(rpObj);
+
+            if (cb.readableBytes() > OBJECT_HEADER_LENGTH) {
+                cb.markReaderIndex();
+                tempObjHeader = PcepObjectHeader.read(cb);
+                cb.resetReaderIndex();
+                yObjClass = tempObjHeader.getObjClass();
+                yObjType = tempObjHeader.getObjType();
+            } else {
+                break;
+            }
+        }
+    }
+
+    /**
+     * Parse TE List from the channel buffer.
+     *
+     * @param cb of type channel buffer
+     * @throws PcepParseException if mandatory fields are missing
+     */
+    public void parseTEList(ChannelBuffer cb) throws PcepParseException {
+        byte yObjClass;
+        byte yObjType;
+
+        llTEObjList = new LinkedList<PcepTEObject>();
+
+        // caller should verify for TE object
+        if (cb.readableBytes() < OBJECT_HEADER_LENGTH) {
+            log.debug("Unable to find TE Object");
+            return;
+        }
+
+        cb.markReaderIndex();
+        PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
+        cb.resetReaderIndex();
+        yObjClass = tempObjHeader.getObjClass();
+        yObjType = tempObjHeader.getObjType();
+        PcepTEObject teObj;
+        while ((yObjClass == PcepTEObjectVer1.TE_OBJ_CLASS) && ((yObjType == PcepTEObjectVer1.TE_OBJ_TYPE_NODE_VALUE)
+                || (yObjType == PcepTEObjectVer1.TE_OBJ_TYPE_LINK_VALUE))) {
+            teObj = PcepTEObjectVer1.read(cb);
+            llTEObjList.add(teObj);
+
+            if (cb.readableBytes() > OBJECT_HEADER_LENGTH) {
+                cb.markReaderIndex();
+                tempObjHeader = PcepObjectHeader.read(cb);
+                cb.resetReaderIndex();
+                yObjClass = tempObjHeader.getObjClass();
+                yObjType = tempObjHeader.getObjType();
+            } else {
+                break;
+            }
+        }
+    }
+
+    /**
+     * parseErrObjList from the channel buffer.
+     *
+     * @param cb of type channel buffer
+     * @throws PcepParseException if mandatory fields are missing
+     */
+    public void parseErrObjList(ChannelBuffer cb) throws PcepParseException {
+        byte yObjClass;
+        byte yObjType;
+        boolean bIsErrorObjFound = false;
+
+        llErrObjList = new LinkedList<PcepErrorObject>();
+
+        // caller should verify for RP object
+        if (cb.readableBytes() < OBJECT_HEADER_LENGTH) {
+            throw new PcepParseException("Unable to find PCEP-ERROR Object");
+        }
+
+        cb.markReaderIndex();
+        PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
+        cb.resetReaderIndex();
+        yObjClass = tempObjHeader.getObjClass();
+        yObjType = tempObjHeader.getObjType();
+        PcepErrorObject errorObject;
+        while ((yObjClass == PcepErrorObjectVer1.ERROR_OBJ_CLASS) && (yObjType == PcepErrorObjectVer1.ERROR_OBJ_TYPE)) {
+            errorObject = PcepErrorObjectVer1.read(cb);
+            llErrObjList.add(errorObject);
+            bIsErrorObjFound = true;
+
+            if (cb.readableBytes() > OBJECT_HEADER_LENGTH) {
+                cb.markReaderIndex();
+                tempObjHeader = PcepObjectHeader.read(cb);
+                cb.resetReaderIndex();
+                yObjClass = tempObjHeader.getObjClass();
+                yObjType = tempObjHeader.getObjType();
+            } else {
+                break;
+            }
+        }
+
+        if (!bIsErrorObjFound) {
+            throw new PcepParseException("At least one PCEP-ERROR Object should be present.");
+        }
+    }
+
+    /**
+     * Reads the byte stream of PcepError from channel buffer.
+     *
+     * @param cb of type channel buffer
+     * @return PcepError error part of PCEP-ERROR
+     * @throws PcepParseException if mandatory fields are missing
+     */
+    public static PcepErrorVer1 read(ChannelBuffer cb) throws PcepParseException {
+        if (cb.readableBytes() < OBJECT_HEADER_LENGTH) {
+            throw new PcepParseException("Unknown Object");
+        }
+
+        PcepErrorVer1 pcepError = new PcepErrorVer1();
+        // check whether any PCEP Error Info is present
+        cb.markReaderIndex();
+        PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
+        cb.resetReaderIndex();
+        byte yObjClass = tempObjHeader.getObjClass();
+
+        //If RPlist present then store it.RPList and TEList are optional
+        if (yObjClass == PcepRPObjectVer1.RP_OBJ_CLASS) {
+            log.debug("RP_LIST");
+            pcepError.parseRPList(cb);
+            yObjClass = checkNextObject(cb);
+        } else if (yObjClass == PcepTEObjectVer1.TE_OBJ_CLASS) {
+            log.debug("TE_LIST");
+            pcepError.parseTEList(cb);
+            yObjClass = checkNextObject(cb);
+        }
+
+        if (yObjClass == PcepErrorObjectVer1.ERROR_OBJ_CLASS) {
+            log.debug("PCEP-ERROR obj list");
+            pcepError.parseErrObjList(cb);
+            yObjClass = checkNextObject(cb);
+        }
+
+        return pcepError;
+    }
+
+    /**
+     * Checks Next Object.
+     *
+     * @param cb of type channel buffer.
+     * @return object type class.
+     */
+    private static byte checkNextObject(ChannelBuffer cb) {
+        if (cb.readableBytes() < OBJECT_HEADER_LENGTH) {
+            return 0;
+        }
+        cb.markReaderIndex();
+        PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
+        cb.resetReaderIndex();
+        return tempObjHeader.getObjClass();
+    }
+
+    /**
+     * Writes the byte stream of PCEP error to the channel buffer.
+     *
+     * @param cb of type channel buffer
+     * @return object length index
+     * @throws PcepParseException if mandatory fields are missing
+     */
+    @Override
+    public int write(ChannelBuffer cb) throws PcepParseException {
+        int iLenStartIndex = cb.writerIndex();
+
+        // RPlist is optional
+        if (this.isErroInfoSet) {
+            ListIterator<PcepRPObject> rpObjlistIterator = this.llRPObjList.listIterator();
+            while (rpObjlistIterator.hasNext()) {
+                rpObjlistIterator.next().write(cb);
+            }
+        }
+
+        // TElist is optional
+        if (this.isTEObjListSet) {
+            ListIterator<PcepTEObject> teObjlistIterator = this.llTEObjList.listIterator();
+            while (teObjlistIterator.hasNext()) {
+                teObjlistIterator.next().write(cb);
+            }
+        }
+        //ErrList is mandatory
+        ListIterator<PcepErrorObject> errlistIterator = this.llErrObjList.listIterator();
+        while (errlistIterator.hasNext()) {
+            errlistIterator.next().write(cb);
+        }
+
+        return cb.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Builder for error part of PCEP-ERROR.
+     */
+    public static class Builder implements PcepError.Builder {
+
+        private LinkedList<PcepRPObject> llRPObjList;
+        private LinkedList<PcepTEObject> llTEObjList;
+        private LinkedList<PcepErrorObject> llErrObjList;
+
+        @Override
+        public PcepError build() {
+            return new PcepErrorVer1(llRPObjList, llTEObjList, llErrObjList);
+        }
+
+        @Override
+        public LinkedList<PcepRPObject> getRPObjList() {
+            return this.llRPObjList;
+        }
+
+        @Override
+        public Builder setRPObjList(LinkedList<PcepRPObject> llRPObjList) {
+            this.llRPObjList = llRPObjList;
+            return this;
+        }
+
+        @Override
+        public LinkedList<PcepTEObject> getTEObjList() {
+            return this.llTEObjList;
+        }
+
+        @Override
+        public Builder setTEObjList(LinkedList<PcepTEObject> llTEObjList) {
+            this.llTEObjList = llTEObjList;
+            return this;
+        }
+
+        @Override
+        public LinkedList<PcepErrorObject> getErrorObjList() {
+            return this.llErrObjList;
+        }
+
+        @Override
+        public Builder setErrorObjList(LinkedList<PcepErrorObject> llErrObjList) {
+            this.llErrObjList = llErrObjList;
+            return this;
+        }
+
+    }
+
+    @Override
+    public void setRPObjList(LinkedList<PcepRPObject> llRPObjList) {
+        this.llRPObjList = llRPObjList;
+    }
+
+    @Override
+    public void setTEObjList(LinkedList<PcepTEObject> llTEObjList) {
+        this.llTEObjList = llTEObjList;
+    }
+
+    @Override
+    public void setErrorObjList(LinkedList<PcepErrorObject> llErrObjList) {
+        this.llErrObjList = llErrObjList;
+    }
+
+    @Override
+    public String toString() {
+        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
+
+        //RP Object list is optional
+        if (null != llRPObjList) {
+            toStrHelper.add("RpObjectList", llRPObjList);
+        }
+
+        //TE Object list is optional
+        if (null != llTEObjList) {
+            toStrHelper.add("TeObjectList", llTEObjList);
+        }
+
+        //Error Object List is mandatory
+        return toStrHelper.add("ErrorObjectList", llErrObjList).toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepOpenMsgVer1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepOpenMsgVer1.java
new file mode 100644
index 0000000..0bbc314
--- /dev/null
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepOpenMsgVer1.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.pcepio.protocol.ver1;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.exceptions.PcepParseException;
+import org.onosproject.pcepio.protocol.PcepMessageReader;
+import org.onosproject.pcepio.protocol.PcepMessageWriter;
+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.PcepErrorDetailInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+public class PcepOpenMsgVer1 implements PcepOpenMsg {
+
+    /*
+     * <Open Message>::= <Common Header> <OPEN>
+     0                   1                   2                   3
+     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    | Ver |  Flags  |  Message-Type |       Message-Length          |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    | Object-Class  |   OT  |Res|P|I|   Object Length (bytes)       |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    | Ver |   Flags |   Keepalive   |  DeadTimer    |      SID      |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |                                                               |
+    //                       Optional TLVs                         //
+    |                                                               |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(PcepOpenMsgVer1.class);
+
+    public static final byte PACKET_VERSION = 1;
+    public static final int PACKET_MINIMUM_LENGTH = 12;
+    public static final PcepType MSG_TYPE = PcepType.OPEN;
+    private PcepOpenObject pcepOpenObj;
+
+    public static final PcepOpenMsgVer1.Reader READER = new Reader();
+
+    /**
+     * Constructor to initialize PcepOpenObject.
+     *
+     * @param pcepOpenObj PCEP-OPEN-OBJECT
+     */
+    public PcepOpenMsgVer1(PcepOpenObject pcepOpenObj) {
+        this.pcepOpenObj = pcepOpenObj;
+    }
+
+    @Override
+    public PcepOpenObject getPcepOpenObject() {
+        return this.pcepOpenObj;
+    }
+
+    @Override
+    public void setPcepOpenObject(PcepOpenObject pcepOpenObj) {
+        this.pcepOpenObj = pcepOpenObj;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public PcepType getType() {
+        return MSG_TYPE;
+    }
+
+    public static class Reader implements PcepMessageReader<PcepOpenMsg> {
+
+        @Override
+        public PcepOpenMsg readFrom(ChannelBuffer cb) throws PcepParseException {
+
+            if (cb.readableBytes() < PACKET_MINIMUM_LENGTH) {
+                throw new PcepParseException("Packet size is less than the minimum length.");
+            }
+
+            byte version = cb.readByte();
+            version = (byte) (version >> PcepMessageVer1.SHIFT_FLAG);
+            if (version != PACKET_VERSION) {
+                log.error("[readFrom] Invalid version: " + version);
+                throw new PcepParseException(PcepErrorDetailInfo.ERROR_TYPE_1, PcepErrorDetailInfo.ERROR_VALUE_1);
+            }
+            // fixed value property type == 1
+            byte type = cb.readByte();
+
+            if (type != MSG_TYPE.getType()) {
+                log.error("[readFrom] Unexpected type: " + type);
+                throw new PcepParseException(PcepErrorDetailInfo.ERROR_TYPE_1, PcepErrorDetailInfo.ERROR_VALUE_1);
+            }
+            int length = cb.readShort();
+            if (length < PACKET_MINIMUM_LENGTH) {
+                throw new PcepParseException(
+                        "Wrong length: Expected to be >= " + PACKET_MINIMUM_LENGTH + ", was: " + length);
+            }
+            return new PcepOpenMsgVer1(PcepOpenObjectVer1.read(cb));
+        }
+    }
+
+    /**
+     * Builder class for PCEP open message.
+     */
+    static class Builder implements PcepOpenMsg.Builder {
+
+        private PcepOpenObject pcepOpenObj;
+
+        @Override
+        public PcepOpenMsg build() throws PcepParseException {
+            if (!(pcepOpenObj instanceof PcepOpenObjectVer1)) {
+                throw new NullPointerException("PcepOpenObject is null.");
+            }
+            return new PcepOpenMsgVer1(pcepOpenObj);
+        }
+
+        @Override
+        public PcepVersion getVersion() {
+            return PcepVersion.PCEP_1;
+        }
+
+        @Override
+        public PcepType getType() {
+            return PcepType.OPEN;
+        }
+
+        @Override
+        public PcepOpenObject getPcepOpenObj() {
+            return this.pcepOpenObj;
+        }
+
+        @Override
+        public Builder setPcepOpenObj(PcepOpenObject obj) {
+            this.pcepOpenObj = obj;
+            return this;
+        }
+    }
+
+    @Override
+    public void writeTo(ChannelBuffer cb) throws PcepParseException {
+        WRITER.write(cb, this);
+    }
+
+    public static final Writer WRITER = new Writer();
+
+    public static class Writer implements PcepMessageWriter<PcepOpenMsgVer1> {
+
+        @Override
+        public void write(ChannelBuffer cb, PcepOpenMsgVer1 message) throws PcepParseException {
+            int startIndex = cb.writerIndex();
+            // first 3 bits set to version
+            cb.writeByte((byte) (PACKET_VERSION << PcepMessageVer1.SHIFT_FLAG));
+            // message type
+            cb.writeByte(MSG_TYPE.getType());
+            // length is length of variable message, will be updated at the end
+            // Store the position of message
+            // length in buffer
+
+            int msgLenIndex = cb.writerIndex();
+            cb.writeShort(0);
+
+            message.getPcepOpenObject().write(cb);
+
+            // update message length field
+            int iLength = cb.writerIndex() - startIndex;
+            cb.setShort(msgLenIndex, (short) iLength);
+        }
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("OpenObject", pcepOpenObj).toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepOpenObjectVer1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepOpenObjectVer1.java
new file mode 100644
index 0000000..3e2a580
--- /dev/null
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepOpenObjectVer1.java
@@ -0,0 +1,483 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.pcepio.protocol.ver1;
+
+import java.util.LinkedList;
+import java.util.ListIterator;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.exceptions.PcepParseException;
+import org.onosproject.pcepio.protocol.PcepOpenObject;
+import org.onosproject.pcepio.protocol.PcepType;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.onosproject.pcepio.types.GmplsCapabilityTlv;
+import org.onosproject.pcepio.types.PceccCapabilityTlv;
+import org.onosproject.pcepio.types.PcepLabelDbVerTlv;
+import org.onosproject.pcepio.types.PcepObjectHeader;
+import org.onosproject.pcepio.types.PcepValueType;
+import org.onosproject.pcepio.types.StatefulLspDbVerTlv;
+import org.onosproject.pcepio.types.StatefulPceCapabilityTlv;
+import org.onosproject.pcepio.types.TedCapabilityTlv;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/*
+     message format.
+      0                   1                   2                   3
+      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    | Object-Class  |   OT  |Res|P|I|   Object Length (bytes)       |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    | Ver |   Flags |   Keepalive   |  DeadTimer    |      SID      |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |                                                               |
+    //                       Optional TLVs                         //
+    |                                                               |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+                     The OPEN Object format
+ */
+
+public class PcepOpenObjectVer1 implements PcepOpenObject {
+
+    protected static final Logger log = LoggerFactory.getLogger(PcepOpenObjectVer1.class);
+
+    public static final PcepType MSG_TYPE = PcepType.OPEN;
+    public static final byte OPEN_OBJECT_VERSION = 1;
+    public static final byte OPEN_OBJ_TYPE = 1;
+    public static final byte OPEN_OBJ_CLASS = 1;
+    public static final byte DEFAULT_KEEPALIVE_TIME = 30;
+    public static final byte DEFAULT_DEAD_TIME = 120;
+    public static final short OPEN_OBJ_MINIMUM_LENGTH = 8;
+    public static final int DEFAULT_GMPLS_CAPABILITY_TLV_IVALUE = 0X0;
+    public static final int DEFAULT_STATEFUL_PCE_CAPABILITY_TLV_IVALUE = 0xf;
+    public static final int DEFAULT_PCECC_CAPABILITY_TLV_IVALUE = 0x7;
+    public static final int DEFAULT_PCEP_LABEL_DB_VER_TLV_IVALUE = 0X0;
+
+    public static final PcepObjectHeader DEFAULT_OPEN_HEADER = new PcepObjectHeader(OPEN_OBJ_CLASS, OPEN_OBJ_TYPE,
+            PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, OPEN_OBJ_MINIMUM_LENGTH);
+
+    private PcepObjectHeader openObjHeader;
+    private byte keepAliveTime;
+    private byte deadTime;
+    private byte sessionId;
+    private LinkedList<PcepValueType> llOptionalTlv;
+
+    /**
+     * Default constructor.
+     */
+    public PcepOpenObjectVer1() {
+        this.openObjHeader = null;
+        this.keepAliveTime = 0;
+        this.deadTime = 0;
+        this.sessionId = 0;
+        this.llOptionalTlv = null;
+    }
+
+    /**
+     * Constructor to initialize all member variables.
+     *
+     * @param openObjHeader Open Object Header
+     * @param keepAliveTime Keepalive timer value
+     * @param deadTime      Dead timer value
+     * @param sessionID     session id
+     * @param llOptionalTlv Optional TLV
+     */
+    public PcepOpenObjectVer1(PcepObjectHeader openObjHeader, byte keepAliveTime, byte deadTime, byte sessionID,
+            LinkedList<PcepValueType> llOptionalTlv) {
+        this.openObjHeader = openObjHeader;
+        this.keepAliveTime = keepAliveTime;
+        this.deadTime = deadTime;
+        this.sessionId = sessionID;
+        this.llOptionalTlv = llOptionalTlv;
+    }
+
+    @Override
+    public PcepObjectHeader getOpenObjHeader() {
+        return this.openObjHeader;
+    }
+
+    @Override
+    public void setOpenObjHeader(PcepObjectHeader obj) {
+        this.openObjHeader = obj;
+    }
+
+    @Override
+    public byte getKeepAliveTime() {
+        return this.keepAliveTime;
+    }
+
+    @Override
+    public void setKeepAliveTime(byte value) {
+        this.keepAliveTime = value;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public byte getDeadTime() {
+        return this.deadTime;
+    }
+
+    @Override
+    public void setDeadTime(byte value) {
+        this.deadTime = value;
+    }
+
+    @Override
+    public byte getSessionId() {
+        return this.sessionId;
+    }
+
+    @Override
+    public void setSessionId(byte value) {
+        this.sessionId = value;
+    }
+
+    @Override
+    public LinkedList<PcepValueType> getOptionalTlv() {
+        return this.llOptionalTlv;
+    }
+
+    @Override
+    public void setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
+        this.llOptionalTlv = llOptionalTlv;
+    }
+
+    /**
+     * Reads from channel buffer and returns object of PcepOpenObject.
+     *
+     * @param cb of type channel buffer
+     * @return object of PcepOpenObject
+     * @throws PcepParseException if mandatory fields are missing
+     */
+    public static PcepOpenObject read(ChannelBuffer cb) throws PcepParseException {
+
+        PcepObjectHeader openObjHeader;
+        byte version;
+        byte keepAliveTime;
+        byte deadTime;
+        byte sessionID;
+        LinkedList<PcepValueType> llOptionalTlv;
+
+        openObjHeader = PcepObjectHeader.read(cb);
+        version = cb.readByte();
+        version = (byte) (version >> PcepMessageVer1.SHIFT_FLAG);
+        if (version != OPEN_OBJECT_VERSION) {
+            throw new PcepParseException("Wrong version: Expected=PcepVersion.PCEP_1(1), got=" + version);
+        }
+        /* Keepalive */
+        keepAliveTime = cb.readByte();
+
+        /* DeadTimer */
+        deadTime = cb.readByte();
+
+        /* SID */
+        sessionID = cb.readByte();
+
+        // Optional TLV
+        llOptionalTlv = parseOptionalTlv(cb);
+
+        return new PcepOpenObjectVer1(openObjHeader, keepAliveTime, deadTime, sessionID, llOptionalTlv);
+    }
+
+    /**
+     * Returns linkedlist of optional tlvs.
+     *
+     * @param cb of type channel buffer
+     * @return llOptionalTlv Optional TLV
+     * @throws PcepParseException if mandatory fields are missing
+     */
+    protected static LinkedList<PcepValueType> parseOptionalTlv(ChannelBuffer cb) throws PcepParseException {
+
+        LinkedList<PcepValueType> llOptionalTlv;
+
+        llOptionalTlv = new LinkedList<PcepValueType>();
+
+        while (4 <= cb.readableBytes()) {
+            PcepValueType tlv;
+            short hType = cb.readShort();
+            short hLength = cb.readShort();
+
+            switch (hType) {
+            case GmplsCapabilityTlv.TYPE:
+                log.debug("GmplsCapabilityTlv");
+                if (GmplsCapabilityTlv.LENGTH != hLength) {
+                    throw new PcepParseException("Invalid length received for Gmpls_Capability_Tlv.");
+                }
+                int iValue = cb.readInt();
+                tlv = new GmplsCapabilityTlv(iValue);
+                break;
+            case StatefulPceCapabilityTlv.TYPE:
+                log.debug("StatefulPceCapabilityTlv");
+                if (StatefulPceCapabilityTlv.LENGTH != hLength) {
+                    throw new PcepParseException("Invalid length received for StatefulPceCapabilityTlv.");
+                }
+                tlv = StatefulPceCapabilityTlv.read(cb);
+                break;
+            case PceccCapabilityTlv.TYPE:
+                log.debug("PceccCapabilityTlv");
+                if (PceccCapabilityTlv.LENGTH != hLength) {
+                    throw new PcepParseException("Invalid length for PceccCapabilityTlv.");
+                }
+                iValue = cb.readInt();
+                tlv = new PceccCapabilityTlv(iValue);
+                break;
+            case StatefulLspDbVerTlv.TYPE:
+                log.debug("StatefulLspDbVerTlv");
+                if (StatefulLspDbVerTlv.LENGTH != hLength) {
+                    throw new PcepParseException("Invalid length received for StatefulLspDbVerTlv.");
+                }
+                long lValue = cb.readLong();
+                tlv = new StatefulLspDbVerTlv(lValue);
+                break;
+            case TedCapabilityTlv.TYPE:
+                log.debug("TedCapabilityTlv");
+                if (TedCapabilityTlv.LENGTH != hLength) {
+                    throw new PcepParseException("Invalid length received for TedCapabilityTlv.");
+                }
+                iValue = cb.readInt();
+                tlv = new TedCapabilityTlv(iValue);
+                break;
+            case PcepLabelDbVerTlv.TYPE:
+                log.debug("PcepLabelDbVerTlv");
+                if (PcepLabelDbVerTlv.LENGTH != hLength) {
+                    throw new PcepParseException("Invalid length received for PcepLabelDbVerTlv.");
+                }
+                lValue = cb.readLong();
+                tlv = new PcepLabelDbVerTlv(lValue);
+                break;
+            default:
+                log.debug("Unsupported TLV: " + hType);
+                cb.skipBytes(hLength);
+                continue;
+            }
+
+            llOptionalTlv.add(tlv);
+        }
+
+        if (0 < cb.readableBytes()) {
+            throw new PcepParseException("Optional Tlv parsing error. Extra bytes received.");
+        }
+
+        return llOptionalTlv;
+    }
+
+    @Override
+    public int write(ChannelBuffer cb) throws PcepParseException {
+
+        int objStartIndex = cb.writerIndex();
+
+        //write common header
+        int objLenIndex = openObjHeader.write(cb);
+
+        if (objLenIndex <= 0) {
+            throw new PcepParseException("Unable to write Open object header.");
+        }
+
+        cb.writeByte((byte) (OPEN_OBJECT_VERSION << PcepMessageVer1.SHIFT_FLAG));
+        cb.writeByte(this.keepAliveTime);
+        cb.writeByte(this.deadTime);
+        cb.writeByte(this.sessionId);
+
+        //Pack optional TLV
+        packOptionalTlv(cb);
+
+        //now write OPEN Object Length
+        int length = cb.writerIndex() - objStartIndex;
+        cb.setShort(objLenIndex, (short) length);
+        //will be helpful during print().
+        this.openObjHeader.setObjLen((short) length);
+
+        return length;
+    }
+
+    /**
+     * Returns writer index.
+     *
+     * @param cb of type channel buffer.
+     * @return writer index
+     */
+    protected int packOptionalTlv(ChannelBuffer cb) {
+        int startIndex = cb.writerIndex();
+
+        LinkedList<PcepValueType> llOptionalTlv = this.llOptionalTlv;
+        ListIterator<PcepValueType> listIterator = llOptionalTlv.listIterator();
+        while (listIterator.hasNext()) {
+            PcepValueType tlv = listIterator.next();
+            if (null == tlv) {
+                log.debug("TLV is null from OptionalTlv list");
+                continue;
+            }
+
+            tlv.write(cb);
+
+            // need to take care of padding
+            int pad = tlv.getLength() % 4;
+
+            if (0 != pad) {
+                pad = 4 - pad;
+                for (int i = 0; i < pad; ++i) {
+                    cb.writeByte((byte) 0);
+                }
+            }
+        }
+
+        return cb.writerIndex() - startIndex;
+    }
+
+    public static class Builder implements PcepOpenObject.Builder {
+        // Pcep open message fields
+        private boolean bIsHeaderSet = false;
+        private PcepObjectHeader openObjHeader;
+        private boolean bIsKeepAliveTimeSet = false;
+        private byte keepAliveTime;
+        private boolean bIsDeadTimeSet = false;
+        private byte deadTime;
+        private boolean bIsSessionIDSet = false;
+        private byte sessionID;
+        private boolean bIsOptionalTlvSet = false;
+        private LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();
+
+        private boolean bIsPFlagSet = false;
+        private boolean bPFlag;
+
+        private boolean bIsIFlagSet = false;
+        private boolean bIFlag;
+
+        @Override
+        public PcepOpenObject build() throws PcepParseException {
+            PcepObjectHeader openObjHeader = this.bIsHeaderSet ? this.openObjHeader : DEFAULT_OPEN_HEADER;
+            byte keepAliveTime = this.bIsKeepAliveTimeSet ? this.keepAliveTime : DEFAULT_KEEPALIVE_TIME;
+            byte deadTime = this.bIsDeadTimeSet ? this.deadTime : DEFAULT_DEAD_TIME;
+
+            if (!this.bIsSessionIDSet) {
+                throw new PcepParseException("SessionID is not set (mandatory)");
+            }
+            if (!this.bIsOptionalTlvSet) {
+                //Add tlv to list
+                //Add GmplsCapabilityTlv
+                PcepValueType tlv;
+                int iValue = DEFAULT_GMPLS_CAPABILITY_TLV_IVALUE;
+                tlv = new GmplsCapabilityTlv(iValue);
+                this.llOptionalTlv.add(tlv);
+
+                //Add StatefulPceCapabilityTlv
+                iValue = DEFAULT_STATEFUL_PCE_CAPABILITY_TLV_IVALUE;
+                tlv = new StatefulPceCapabilityTlv(iValue);
+                this.llOptionalTlv.add(tlv);
+
+            }
+
+            if (bIsPFlagSet) {
+                openObjHeader.setPFlag(bPFlag);
+            }
+
+            if (bIsIFlagSet) {
+                openObjHeader.setIFlag(bIFlag);
+            }
+
+            return new PcepOpenObjectVer1(openObjHeader, keepAliveTime, deadTime, this.sessionID, this.llOptionalTlv);
+        }
+
+        @Override
+        public PcepObjectHeader getOpenObjHeader() {
+            return this.openObjHeader;
+        }
+
+        @Override
+        public Builder setOpenObjHeader(PcepObjectHeader obj) {
+            this.openObjHeader = obj;
+            this.bIsHeaderSet = true;
+            return this;
+        }
+
+        @Override
+        public byte getKeepAliveTime() {
+            return this.keepAliveTime;
+        }
+
+        @Override
+        public Builder setKeepAliveTime(byte value) {
+            this.keepAliveTime = value;
+            this.bIsKeepAliveTimeSet = true;
+            return this;
+        }
+
+        @Override
+        public byte getDeadTime() {
+            return this.deadTime;
+        }
+
+        @Override
+        public Builder setDeadTime(byte value) {
+            this.deadTime = value;
+            this.bIsDeadTimeSet = true;
+            return this;
+        }
+
+        @Override
+        public byte getSessionId() {
+            return this.sessionID;
+        }
+
+        @Override
+        public Builder setSessionId(byte value) {
+            this.sessionID = value;
+            this.bIsSessionIDSet = true;
+            return this;
+        }
+
+        @Override
+        public Builder setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
+            this.llOptionalTlv = llOptionalTlv;
+            this.bIsOptionalTlvSet = true;
+            return this;
+        }
+
+        @Override
+        public LinkedList<PcepValueType> getOptionalTlv() {
+            return this.llOptionalTlv;
+        }
+
+        @Override
+        public Builder setPFlag(boolean value) {
+            this.bPFlag = value;
+            this.bIsPFlagSet = true;
+            return this;
+        }
+
+        @Override
+        public Builder setIFlag(boolean value) {
+            this.bIFlag = value;
+            this.bIsIFlagSet = true;
+            return this;
+        }
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("ObjectHeader", openObjHeader)
+                .add("Keepalive", keepAliveTime).add("DeadTimer", deadTime).add("SessionId", sessionId)
+                .add("OptionalTlv", llOptionalTlv).toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepRPObjectVer1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepRPObjectVer1.java
new file mode 100644
index 0000000..6055642
--- /dev/null
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepRPObjectVer1.java
@@ -0,0 +1,433 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.pcepio.protocol.ver1;
+
+import java.util.LinkedList;
+import java.util.ListIterator;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.exceptions.PcepParseException;
+import org.onosproject.pcepio.protocol.PcepRPObject;
+import org.onosproject.pcepio.types.PcepObjectHeader;
+import org.onosproject.pcepio.types.PcepValueType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+public class PcepRPObjectVer1 implements PcepRPObject {
+
+    /*
+     *  RP Object.
+    0                   1                   2                   3
+    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |                          Flags                    |O|B|R| Pri |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |                        Request-ID-number                      |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |                                                               |
+    //                      Optional TLVs                          //
+    |                                                               |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(PcepRPObjectVer1.class);
+
+    public static final byte RP_OBJ_TYPE = 1;
+    public static final byte RP_OBJ_CLASS = 2;
+    public static final byte RP_OBJECT_VERSION = 1;
+    public static final short RP_OBJ_MINIMUM_LENGTH = 12;
+
+    public static final int DEFAULT_REQUEST_ID_NUM = 0;
+    //Signalled , all default values to be checked.
+    public static final boolean DEFAULT_OFLAG = false;
+    public static final boolean DEFAULT_BFLAG = false;
+    public static final boolean DEFAULT_RFLAG = false;
+    public static final byte DEFAULT_PRIFLAG = 0;
+    public static final int OBJECT_HEADER_LENGTH = 4;
+    public static final int OFLAG_SHIFT_VALUE = 5;
+    public static final int BFLAG_SHIFT_VALUE = 4;
+    public static final int RFLAG_SHIFT_VALUE = 3;
+    public static final int OFLAG_TEMP_SHIFT_VALUE = 0x20;
+    public static final int BFLAG_TEMP_SHIFT_VALUE = 0x10;
+    public static final int RFLAG_TEMP_SHIFT_VALUE = 0x08;
+    public static final int PRIFLAG_TEMP_SHIFT_VALUE = 0x07;
+    public static final int BIT_SET = 1;
+    public static final int BIT_RESET = 0;
+    public static final int MINIMUM_COMMON_HEADER_LENGTH = 4;
+
+    public static final PcepObjectHeader DEFAULT_RP_OBJECT_HEADER = new PcepObjectHeader(RP_OBJ_CLASS, RP_OBJ_TYPE,
+            PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, RP_OBJ_MINIMUM_LENGTH);
+
+    private PcepObjectHeader rpObjHeader;
+    private int iRequestIdNum;
+    private boolean bOFlag;
+    private boolean bBFlag;
+    private boolean bRFlag;
+    private byte yPriFlag; // 3bytes
+    private LinkedList<PcepValueType> llOptionalTlv;
+
+    /**
+     * Constructor to initialize variables.
+     *
+     * @param rpObjHeader RP-OBJECT header
+     * @param iRequestIdNum Request-ID-number
+     * @param bOFlag O-flag
+     * @param bBFlag B-flag
+     * @param bRFlag R-flag
+     * @param yPriFlag Pri-flag
+     * @param llOptionalTlv linked list of Optional TLV
+     */
+    public PcepRPObjectVer1(PcepObjectHeader rpObjHeader, int iRequestIdNum, boolean bOFlag, boolean bBFlag,
+            boolean bRFlag, byte yPriFlag, LinkedList<PcepValueType> llOptionalTlv) {
+        this.rpObjHeader = rpObjHeader;
+        this.iRequestIdNum = iRequestIdNum;
+        this.bOFlag = bOFlag;
+        this.bBFlag = bBFlag;
+        this.bRFlag = bRFlag;
+        this.yPriFlag = yPriFlag;
+        this.llOptionalTlv = llOptionalTlv;
+    }
+
+    /**
+     * Sets RP Object header.
+     *
+     * @param obj RP Object header
+     */
+    public void setRPObjHeader(PcepObjectHeader obj) {
+        this.rpObjHeader = obj;
+    }
+
+    @Override
+    public void setRequestIdNum(int iRequestIdNum) {
+        this.iRequestIdNum = iRequestIdNum;
+    }
+
+    @Override
+    public void setOFlag(boolean bOFlag) {
+        this.bOFlag = bOFlag;
+    }
+
+    @Override
+    public void setBFlag(boolean bBFlag) {
+        this.bBFlag = bBFlag;
+    }
+
+    @Override
+    public void setRFlag(boolean bRFlag) {
+        this.bRFlag = bRFlag;
+    }
+
+    @Override
+    public void setPriFlag(byte yPriFlag) {
+        this.yPriFlag = yPriFlag;
+    }
+
+    /**
+     * Returns RP Object header.
+     *
+     * @return rpObjHeader
+     */
+    public PcepObjectHeader getRPObjHeader() {
+        return this.rpObjHeader;
+    }
+
+    @Override
+    public int getRequestIdNum() {
+        return this.iRequestIdNum;
+    }
+
+    @Override
+    public boolean getOFlag() {
+        return this.bOFlag;
+    }
+
+    @Override
+    public boolean getBFlag() {
+        return this.bBFlag;
+    }
+
+    @Override
+    public boolean getRFlag() {
+        return this.bRFlag;
+    }
+
+    @Override
+    public byte getPriFlag() {
+        return this.yPriFlag;
+    }
+
+    /**
+     * Reads the channel buffer and returns the object of PcepRPObject.
+     *
+     * @param cb of type channel buffer
+     * @return the object of PcepRPObject
+     * @throws PcepParseException if mandatory fields are missing
+     */
+    public static PcepRPObject read(ChannelBuffer cb) throws PcepParseException {
+        log.debug("read");
+        PcepObjectHeader rpObjHeader;
+        int iRequestIdNum;
+        boolean bOFlag;
+        boolean bBFlag;
+        boolean bRFlag;
+        byte yPriFlag; // 3bytes
+        LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();
+
+        rpObjHeader = PcepObjectHeader.read(cb);
+
+        //take only LspObject buffer.
+        ChannelBuffer tempCb = cb.readBytes(rpObjHeader.getObjLen() - OBJECT_HEADER_LENGTH);
+
+        int iTemp = tempCb.readInt();
+        yPriFlag = (byte) (iTemp & PRIFLAG_TEMP_SHIFT_VALUE);
+        bOFlag = (iTemp & OFLAG_TEMP_SHIFT_VALUE) == OFLAG_TEMP_SHIFT_VALUE ? true : false;
+        bBFlag = (iTemp & BFLAG_TEMP_SHIFT_VALUE) == BFLAG_TEMP_SHIFT_VALUE ? true : false;
+        bRFlag = (iTemp & RFLAG_TEMP_SHIFT_VALUE) == RFLAG_TEMP_SHIFT_VALUE ? true : false;
+
+        iRequestIdNum = tempCb.readInt();
+
+        // parse optional TLV
+        llOptionalTlv = parseOptionalTlv(tempCb);
+
+        return new PcepRPObjectVer1(rpObjHeader, iRequestIdNum, bOFlag, bBFlag, bRFlag, yPriFlag, llOptionalTlv);
+    }
+
+    @Override
+    public int write(ChannelBuffer cb) throws PcepParseException {
+
+        //write Object header
+        int objStartIndex = cb.writerIndex();
+
+        int objLenIndex = rpObjHeader.write(cb);
+
+        if (objLenIndex <= 0) {
+            throw new PcepParseException("ObjectLength Index is " + objLenIndex);
+        }
+        int iTemp;
+        iTemp = (yPriFlag);
+
+        iTemp = (bOFlag) ? (iTemp | OFLAG_SHIFT_VALUE) : iTemp;
+        iTemp = (bBFlag) ? (iTemp | BFLAG_SHIFT_VALUE) : iTemp;
+        iTemp = (bRFlag) ? (iTemp | RFLAG_SHIFT_VALUE) : iTemp;
+
+        cb.writeInt(iTemp);
+        cb.writeInt(iRequestIdNum);
+
+        // Add optional TLV
+        packOptionalTlv(cb);
+
+        //Update object length now
+        int length = cb.writerIndex() - objStartIndex;
+
+        //will be helpful during print().
+        rpObjHeader.setObjLen((short) length);
+
+        cb.setShort(objLenIndex, (short) length);
+        return cb.writerIndex();
+    }
+
+    /**
+     * Returns list of optional tlvs.
+     *
+     * @param cb of type channel buffer.
+     * @return llOutOptionalTlv linked list of Optional TLV
+     * @throws PcepParseException if mandatory fields are missing
+     */
+    protected static LinkedList<PcepValueType> parseOptionalTlv(ChannelBuffer cb) throws PcepParseException {
+
+        LinkedList<PcepValueType> llOutOptionalTlv = new LinkedList<PcepValueType>();
+        //Currently no optional TLvs, will be added based on requirements.
+        return llOutOptionalTlv;
+    }
+
+    /**
+     * Returns optional tlvs.
+     *
+     * @param cb of type channel buffer
+     * @return llOptionalTlv linked list of Optional TLV
+     */
+    protected int packOptionalTlv(ChannelBuffer cb) {
+
+        ListIterator<PcepValueType> listIterator = llOptionalTlv.listIterator();
+        while (listIterator.hasNext()) {
+            listIterator.next().write(cb);
+        }
+
+        return cb.writerIndex();
+    }
+
+    public static class Builder implements PcepRPObject.Builder {
+
+        private boolean bIsHeaderSet = false;
+        private boolean bIsRequestIdNumSet = false;
+        private boolean bIsOFlagSet = false;
+        private boolean bIsRFlagset = false;
+        private boolean bIsBFlagSet = false;
+        private boolean bIsPriFlagSet = false;
+
+        private PcepObjectHeader rpObjHeader;
+        private int requestIdNum;
+        private boolean bOFlag;
+        private boolean bBFlag;
+        private boolean bRFlag;
+        private byte yPriFlag;
+        private LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();
+
+        private boolean bIsPFlagSet = false;
+        private boolean bPFlag;
+
+        private boolean bIsIFlagSet = false;
+        private boolean bIFlag;
+
+        @Override
+        public PcepRPObject build() {
+            PcepObjectHeader lspObjHeader = this.bIsHeaderSet ? this.rpObjHeader : DEFAULT_RP_OBJECT_HEADER;
+
+            int requestIdNum = this.bIsRequestIdNumSet ? this.requestIdNum : DEFAULT_REQUEST_ID_NUM;
+            boolean bOFlag = this.bIsOFlagSet ? this.bOFlag : DEFAULT_OFLAG;
+            boolean bBFlag = this.bIsBFlagSet ? this.bBFlag : DEFAULT_BFLAG;
+            boolean bRFlag = this.bIsRFlagset ? this.bRFlag : DEFAULT_RFLAG;
+            byte yPriFlag = this.bIsPriFlagSet ? this.yPriFlag : DEFAULT_PRIFLAG;
+
+            if (bIsPFlagSet) {
+                lspObjHeader.setPFlag(bPFlag);
+            }
+
+            if (bIsIFlagSet) {
+                lspObjHeader.setIFlag(bIFlag);
+            }
+
+            return new PcepRPObjectVer1(lspObjHeader, requestIdNum, bOFlag, bBFlag, bRFlag, yPriFlag, llOptionalTlv);
+        }
+
+        @Override
+        public PcepObjectHeader getRPObjHeader() {
+            return this.rpObjHeader;
+        }
+
+        @Override
+        public Builder setRPObjHeader(PcepObjectHeader obj) {
+            this.rpObjHeader = obj;
+            this.bIsHeaderSet = true;
+            return this;
+        }
+
+        @Override
+        public int getRequestIdNum() {
+            return this.requestIdNum;
+        }
+
+        @Override
+        public Builder setRequestIdNum(int value) {
+            this.requestIdNum = value;
+            this.bIsRequestIdNumSet = true;
+            return this;
+        }
+
+        @Override
+        public Builder setOFlag(boolean value) {
+            this.bOFlag = value;
+            this.bIsOFlagSet = true;
+            return this;
+        }
+
+        @Override
+        public boolean getBFlag() {
+            return this.bBFlag;
+        }
+
+        @Override
+        public Builder setBFlag(boolean value) {
+            this.bBFlag = value;
+            this.bIsBFlagSet = true;
+            return this;
+        }
+
+        @Override
+        public boolean getRFlag() {
+            return this.bRFlag;
+        }
+
+        @Override
+        public Builder setRFlag(boolean value) {
+            this.bRFlag = value;
+            this.bIsRFlagset = true;
+            return this;
+        }
+
+        @Override
+        public byte getPriFlag() {
+            return this.yPriFlag;
+        }
+
+        @Override
+        public Builder setPriFlag(byte value) {
+            this.yPriFlag = value;
+            this.bIsPriFlagSet = true;
+            return this;
+        }
+
+        @Override
+        public Builder setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
+            this.llOptionalTlv = llOptionalTlv;
+            return this;
+        }
+
+        @Override
+        public LinkedList<PcepValueType> getOptionalTlv() {
+            return this.llOptionalTlv;
+        }
+
+        @Override
+        public Builder setPFlag(boolean value) {
+            this.bPFlag = value;
+            this.bIsPFlagSet = true;
+            return this;
+        }
+
+        @Override
+        public Builder setIFlag(boolean value) {
+            this.bIFlag = value;
+            this.bIsIFlagSet = true;
+            return this;
+        }
+
+        @Override
+        public boolean getOFlag() {
+            return this.bOFlag;
+        }
+
+    }
+
+    @Override
+    public LinkedList<PcepValueType> getOptionalTlv() {
+        return this.llOptionalTlv;
+    }
+
+    @Override
+    public void setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
+        this.llOptionalTlv = llOptionalTlv;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("ObjectHeader", rpObjHeader).add("OFlag", (bOFlag) ? 1 : 0)
+                .add("BFlag", (bBFlag) ? 1 : 0).add("RFlag", (bRFlag) ? 1 : 0).add("PriFlag", yPriFlag)
+                .add("RequestIdNumber", iRequestIdNum).add("OptionalTlv", llOptionalTlv).toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepTEObjectVer1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepTEObjectVer1.java
new file mode 100644
index 0000000..b32a9e0
--- /dev/null
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepTEObjectVer1.java
@@ -0,0 +1,498 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.pcepio.protocol.ver1;
+
+import java.util.LinkedList;
+import java.util.ListIterator;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.exceptions.PcepParseException;
+import org.onosproject.pcepio.protocol.PcepTEObject;
+import org.onosproject.pcepio.types.LocalTENodeDescriptorsTLV;
+import org.onosproject.pcepio.types.PcepObjectHeader;
+import org.onosproject.pcepio.types.PcepValueType;
+import org.onosproject.pcepio.types.RemoteTENodeDescriptorsTLV;
+import org.onosproject.pcepio.types.RoutingUniverseTLV;
+import org.onosproject.pcepio.types.TELinkAttributesTlv;
+import org.onosproject.pcepio.types.TELinkDescriptorsTLV;
+import org.onosproject.pcepio.types.TENodeAttributesTlv;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+public class PcepTEObjectVer1 implements PcepTEObject {
+    /*
+     *
+    reference: PCEP Extension for Transporting TE Data draft-dhodylee-pce-pcep-te-data-extn-02.
+    TE Object-Class is [TBD6].
+
+    Two Object-Type values are defined for the TE object:
+
+    o  TE Node: TE Object-Type is 1.
+
+    o  TE Link: TE Object-Type is 2.
+
+    The format of the TE object body is as follows:
+
+       0                   1                   2                   3
+       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+      |  Protocol-ID  |          Flag                             |R|S|
+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+      |                          TE-ID                                |
+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+      //                         TLVs                                //
+      |                                                               |
+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(PcepTEObjectVer1.class);
+
+    public static final byte TE_OBJ_TYPE_NODE_VALUE = 1;
+    public static final byte TE_OBJ_TYPE_LINK_VALUE = 2;
+
+    public static final byte TE_OBJ_CLASS = 101; //TBD6 in RFC.
+    public static final byte TE_OBJECT_VERSION = 1;
+
+    // TE_OBJ_MINIMUM_LENGTH = TEObjectHeaderLen(4)+ TEObjectLen(8)
+    public static final short TE_OBJ_MINIMUM_LENGTH = 12;
+
+    // Signaled ,all default values to be checked.
+    public static final byte DEFAULT_PROTOCOL_ID = 1; //IS-IS Level 1
+    public static final boolean DEFAULT_R_FLAG = false;
+    public static final boolean DEFAULT_S_FLAG = false;
+    public static final int DEFAULT_TE_ID = 0;
+
+    public static final int OBJECT_HEADER_LENGTH = 4;
+    public static final int RIGHT_SHIFT_ONE = 1;
+    public static final int RIGHT_FIRST_FLAG = 0x1;
+    public static final int FLAG_SET_R_FLAG = 0x2;
+    public static final int FLAG_SET_S_FLAG = 0x1;
+    public static final int MINIMUM_COMMON_HEADER_LENGTH = 4;
+    public static final int MINIMUM_TLV_HEADER_LENGTH = 4;
+
+    public static final PcepObjectHeader DEFAULT_TE_OBJECT_HEADER = new PcepObjectHeader(TE_OBJ_CLASS,
+            TE_OBJ_TYPE_NODE_VALUE, PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED,
+            TE_OBJ_MINIMUM_LENGTH);
+
+    private PcepObjectHeader teObjHeader;
+    private byte yProtocolId;
+    // 2-flags
+    private boolean bRFlag;
+    private boolean bSFlag;
+    private int iTEId;
+    // Optional TLV
+    private LinkedList<PcepValueType> llOptionalTlv;
+
+    /**
+     * Constructor to initialize variables.
+     *
+     * @param teObjHeader TE Object header
+     * @param yProtocolId Protocol-ID
+     * @param bRFlag R-flag
+     * @param bSFlag S-flag
+     * @param iTEId TE-ID
+     * @param llOptionalTlv linked list of Optional TLV
+     */
+    public PcepTEObjectVer1(PcepObjectHeader teObjHeader, byte yProtocolId, boolean bRFlag, boolean bSFlag, int iTEId,
+            LinkedList<PcepValueType> llOptionalTlv) {
+
+        this.teObjHeader = teObjHeader;
+        this.yProtocolId = yProtocolId;
+        this.bRFlag = bRFlag;
+        this.bSFlag = bSFlag;
+        this.iTEId = iTEId;
+        this.llOptionalTlv = llOptionalTlv;
+    }
+
+    @Override
+    public PcepObjectHeader getTEObjHeader() {
+        return this.teObjHeader;
+    }
+
+    @Override
+    public void setTEObjHeader(PcepObjectHeader obj) {
+        this.teObjHeader = obj;
+    }
+
+    @Override
+    public byte getProtocolId() {
+        return this.yProtocolId;
+    }
+
+    @Override
+    public void setProtocolId(byte yProtId) {
+        this.yProtocolId = yProtId;
+    }
+
+    @Override
+    public boolean getRFlag() {
+        return this.bRFlag;
+    }
+
+    @Override
+    public void setRFlag(boolean bRFlag) {
+        this.bRFlag = bRFlag;
+    }
+
+    @Override
+    public boolean getSFlag() {
+        return this.bSFlag;
+    }
+
+    @Override
+    public void setSFlag(boolean bSFlag) {
+        this.bSFlag = bSFlag;
+    }
+
+    @Override
+    public int getTEId() {
+        return this.iTEId;
+    }
+
+    @Override
+    public void setTEId(int iTEId) {
+        this.iTEId = iTEId;
+    }
+
+    @Override
+    public LinkedList<PcepValueType> getOptionalTlv() {
+        return this.llOptionalTlv;
+    }
+
+    @Override
+    public void setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
+        this.llOptionalTlv = llOptionalTlv;
+    }
+
+    /**
+     * Reads from the channel buffer and returns Object of PcepTEObject.
+     *
+     * @param cb of type channel buffer
+     * @return Object of PcepTEObject
+     * @throws PcepParseException if mandatory fields are missing
+     */
+    public static PcepTEObject read(ChannelBuffer cb) throws PcepParseException {
+        log.debug("read");
+
+        PcepObjectHeader teObjHeader;
+        byte yProtocolId;
+        // 2-flags
+        boolean bRFlag;
+        boolean bSFlag;
+        int iTEId;
+        LinkedList<PcepValueType> llOptionalTlv;
+
+        teObjHeader = PcepObjectHeader.read(cb);
+
+        //take only TEObject buffer.
+        ChannelBuffer tempCb = cb.readBytes(teObjHeader.getObjLen() - OBJECT_HEADER_LENGTH);
+
+        yProtocolId = tempCb.readByte();
+        //ignore first two bytes of Flags
+        tempCb.readShort();
+
+        Integer iTemp = (int) tempCb.readByte(); //read 3rd byte Flag
+        bSFlag = ((iTemp & FLAG_SET_S_FLAG) == FLAG_SET_S_FLAG) ? true : false;
+        bRFlag = ((iTemp & FLAG_SET_R_FLAG) == FLAG_SET_R_FLAG) ? true : false;
+
+        iTEId = tempCb.readInt();
+
+        // parse optional TLV
+        llOptionalTlv = parseOptionalTlv(tempCb);
+
+        return new PcepTEObjectVer1(teObjHeader, yProtocolId, bRFlag, bSFlag, iTEId, llOptionalTlv);
+    }
+
+    @Override
+    public int write(ChannelBuffer cb) throws PcepParseException {
+
+        //write Object header
+        int objStartIndex = cb.writerIndex();
+        int objLenIndex = teObjHeader.write(cb);
+
+        if (objLenIndex <= 0) {
+            throw new PcepParseException("ObjectLength Index is " + objLenIndex);
+        }
+
+        //write Protocol ID
+        cb.writeByte(this.yProtocolId);
+
+        //write Flag
+        cb.writeShort(0);
+
+        byte bTemp = 0;
+        if (bSFlag) {
+            bTemp = FLAG_SET_S_FLAG;
+        }
+
+        if (bRFlag) {
+            bTemp = (byte) (bTemp | FLAG_SET_R_FLAG);
+        }
+        cb.writeByte(bTemp);
+
+        //write TEId
+        cb.writeInt(iTEId);
+
+        // Add optional TLV
+        packOptionalTlv(cb);
+
+        //Update object length now
+        int length = cb.writerIndex() - objStartIndex;
+
+        //will be helpful during print().
+        teObjHeader.setObjLen((short) length);
+
+        cb.setShort(objLenIndex, (short) length);
+
+        return cb.writerIndex();
+    }
+
+    /**
+     * Returns Linked list of PCEP Value Type.
+     *
+     * @param cb of channel buffer
+     * @return Linked list of PCEP Value Type
+     * @throws PcepParseException if mandatory fields are missing
+     */
+    protected static LinkedList<PcepValueType> parseOptionalTlv(ChannelBuffer cb) throws PcepParseException {
+
+        LinkedList<PcepValueType> llOutOptionalTlv;
+
+        llOutOptionalTlv = new LinkedList<PcepValueType>();
+
+        while (MINIMUM_TLV_HEADER_LENGTH <= cb.readableBytes()) {
+
+            PcepValueType tlv;
+            short hType = cb.readShort();
+            short hLength = cb.readShort();
+            long lValue = 0;
+
+            switch (hType) {
+
+            case RoutingUniverseTLV.TYPE:
+                lValue = cb.readLong();
+                tlv = new RoutingUniverseTLV(lValue);
+                break;
+            case LocalTENodeDescriptorsTLV.TYPE:
+                tlv = LocalTENodeDescriptorsTLV.read(cb, hLength);
+                break;
+            case RemoteTENodeDescriptorsTLV.TYPE:
+                RemoteTENodeDescriptorsTLV.hLength = hLength;
+                tlv = RemoteTENodeDescriptorsTLV.read(cb);
+                break;
+            case TELinkDescriptorsTLV.TYPE:
+                tlv = TELinkDescriptorsTLV.read(cb, hLength);
+                break;
+            case TENodeAttributesTlv.TYPE:
+                tlv = TENodeAttributesTlv.read(cb, hLength);
+                break;
+            case TELinkAttributesTlv.TYPE:
+                tlv = TELinkAttributesTlv.read(cb, hLength);
+                break;
+            default:
+                throw new PcepParseException("Unsupported TLV type :" + hType);
+            }
+
+            // Check for the padding
+            int pad = hLength % 4;
+            if (0 < pad) {
+                pad = 4 - pad;
+                if (pad <= cb.readableBytes()) {
+                    cb.skipBytes(pad);
+                }
+            }
+
+            llOutOptionalTlv.add(tlv);
+        }
+
+        if (0 < cb.readableBytes()) {
+
+            throw new PcepParseException("Optional Tlv parsing error. Extra bytes received.");
+        }
+
+        return llOutOptionalTlv;
+    }
+
+    /**
+     * Returns the writer index.
+     *
+     * @param cb of type channel buffer
+     * @return the writer index.
+     */
+    protected int packOptionalTlv(ChannelBuffer cb) {
+
+        ListIterator<PcepValueType> listIterator = llOptionalTlv.listIterator();
+
+        while (listIterator.hasNext()) {
+            PcepValueType tlv = listIterator.next();
+
+            if (null == tlv) {
+                log.debug("TLV is null from OptionalTlv list");
+                continue;
+            }
+            tlv.write(cb);
+
+            // need to take care of padding
+            int pad = tlv.getLength() % 4;
+
+            if (0 != pad) {
+                pad = 4 - pad;
+                for (int i = 0; i < pad; ++i) {
+                    cb.writeByte((byte) 0);
+                }
+            }
+        }
+
+        return cb.writerIndex();
+    }
+
+    public static class Builder implements PcepTEObject.Builder {
+        private boolean bIsHeaderSet = false;
+        private boolean bIsProtocolIdSet = false;
+        private boolean bIsRFlagSet = false;
+        private boolean bIsSFlagSet = false;
+        private boolean bIsTEIdSet = false;
+
+        private PcepObjectHeader teObjHeader;
+        private byte yProtocolId;
+        private boolean bRFlag;
+        private boolean bSFlag;
+        private int iTEId;
+        private LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();
+
+        private boolean bIsPFlagSet = false;
+        private boolean bPFlag;
+
+        private boolean bIsIFlagSet = false;
+        private boolean bIFlag;
+
+        @Override
+        public PcepTEObject build() {
+            PcepObjectHeader teObjHeader = this.bIsHeaderSet ? this.teObjHeader : DEFAULT_TE_OBJECT_HEADER;
+
+            byte yProtocolId = this.bIsProtocolIdSet ? this.yProtocolId : DEFAULT_PROTOCOL_ID;
+            boolean bRFlag = this.bIsRFlagSet ? this.bRFlag : DEFAULT_R_FLAG;
+            boolean bSFlag = this.bIsSFlagSet ? this.bSFlag : DEFAULT_S_FLAG;
+            int iTEId = this.bIsTEIdSet ? this.iTEId : DEFAULT_TE_ID;
+
+            if (bIsPFlagSet) {
+                teObjHeader.setPFlag(bPFlag);
+            }
+
+            if (bIsIFlagSet) {
+                teObjHeader.setIFlag(bIFlag);
+            }
+
+            return new PcepTEObjectVer1(teObjHeader, yProtocolId, bRFlag, bSFlag, iTEId, llOptionalTlv);
+
+        }
+
+        @Override
+        public PcepObjectHeader getTEObjHeader() {
+            return this.teObjHeader;
+        }
+
+        @Override
+        public Builder setTEObjHeader(PcepObjectHeader obj) {
+            this.teObjHeader = obj;
+            this.bIsHeaderSet = true;
+            return this;
+        }
+
+        @Override
+        public byte getProtocolId() {
+            return this.yProtocolId;
+        }
+
+        @Override
+        public Builder setProtocolId(byte yProtId) {
+            this.yProtocolId = yProtId;
+            this.bIsProtocolIdSet = true;
+            return this;
+        }
+
+        @Override
+        public boolean getRFlag() {
+            return this.bRFlag;
+        }
+
+        @Override
+        public Builder setRFlag(boolean bRFlag) {
+            this.bRFlag = bRFlag;
+            this.bIsRFlagSet = true;
+            return this;
+        }
+
+        @Override
+        public boolean getSFlag() {
+            return this.bSFlag;
+        }
+
+        @Override
+        public Builder setSFlag(boolean bSFlag) {
+            this.bSFlag = bSFlag;
+            this.bIsSFlagSet = true;
+            return this;
+        }
+
+        @Override
+        public int getTEId() {
+            return this.iTEId;
+        }
+
+        @Override
+        public Builder setTEId(int iTEId) {
+            this.iTEId = iTEId;
+            this.bIsTEIdSet = true;
+            return this;
+        }
+
+        @Override
+        public LinkedList<PcepValueType> getOptionalTlv() {
+            return this.llOptionalTlv;
+        }
+
+        @Override
+        public Builder setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
+            this.llOptionalTlv = llOptionalTlv;
+            return this;
+        }
+
+        @Override
+        public Builder setPFlag(boolean value) {
+            this.bPFlag = value;
+            this.bIsPFlagSet = true;
+            return this;
+        }
+
+        @Override
+        public Builder setIFlag(boolean value) {
+            this.bIFlag = value;
+            this.bIsIFlagSet = true;
+            return this;
+        }
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("ObjectHeader", teObjHeader).add("ProtocolId", yProtocolId)
+                .add("RFlag", (bRFlag) ? 1 : 0).add("SFlag", (bSFlag) ? 1 : 0).add("TeId", iTEId)
+                .add("OptionalTlv", llOptionalTlv).toString();
+    }
+}
