diff --git a/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPMessageWriter.java b/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPMessageWriter.java
new file mode 100644
index 0000000..11f161c
--- /dev/null
+++ b/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPMessageWriter.java
@@ -0,0 +1,36 @@
+/*
+ * 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.bgpio.protocol;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.bgpio.exceptions.BGPParseException;
+
+/**
+ * Abstraction of an entity providing BGP Message Writer.
+ */
+public interface BGPMessageWriter<T> {
+
+    /**
+     * Writes the Objects of the BGP Message into Channel Buffer.
+     *
+     * @param cb Channel Buffer
+     * @param message BGP Message
+     * @throws BGPParseException
+     *                     While writing message
+     */
+     void write(ChannelBuffer cb, T message) throws BGPParseException;
+}
\ No newline at end of file
diff --git a/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/IGPRouterID.java b/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/IGPRouterID.java
new file mode 100644
index 0000000..377d12b
--- /dev/null
+++ b/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/IGPRouterID.java
@@ -0,0 +1,23 @@
+/*
+ * 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.bgpio.protocol;
+
+/**
+ * Provides Abstraction of IGP RouterID TLV.
+ */
+public interface IGPRouterID {
+}
\ No newline at end of file
diff --git a/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPPrefixLSIdentifier.java b/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPPrefixLSIdentifier.java
new file mode 100644
index 0000000..4fef47f
--- /dev/null
+++ b/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPPrefixLSIdentifier.java
@@ -0,0 +1,228 @@
+/*
+ * 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.bgpio.protocol.link_state;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.bgpio.exceptions.BGPParseException;
+import org.onosproject.bgpio.types.BGPErrorType;
+import org.onosproject.bgpio.types.BGPValueType;
+import org.onosproject.bgpio.types.IPReachabilityInformationTlv;
+import org.onosproject.bgpio.types.OSPFRouteTypeTlv;
+import org.onosproject.bgpio.types.attr.BgpAttrNodeMultiTopologyId;
+import org.onosproject.bgpio.util.UnSupportedAttribute;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides Implementation of Local node descriptors and prefix descriptors.
+ */
+public class BGPPrefixLSIdentifier {
+
+    protected static final Logger log = LoggerFactory.getLogger(BGPPrefixLSIdentifier.class);
+    public static final int TYPE_AND_LEN = 4;
+    private NodeDescriptors localNodeDescriptors;
+    private LinkedList<BGPValueType> prefixDescriptor;
+
+    /**
+     * Resets parameters.
+     */
+    public BGPPrefixLSIdentifier() {
+        this.localNodeDescriptors = null;
+        this.prefixDescriptor = null;
+    }
+
+    /**
+     * Constructor to initialize parameters.
+     *
+     * @param localNodeDescriptors Local node descriptors
+     * @param prefixDescriptor Prefix Descriptors
+     */
+    public BGPPrefixLSIdentifier(NodeDescriptors localNodeDescriptors, LinkedList<BGPValueType> prefixDescriptor) {
+        this.localNodeDescriptors = localNodeDescriptors;
+        this.prefixDescriptor = prefixDescriptor;
+    }
+
+    /**
+     * Reads the channel buffer and parses Prefix Identifier.
+     *
+     * @param cb ChannelBuffer
+     * @param protocolId protocol ID
+     * @return object of this class
+     * @throws BGPParseException while parsing Prefix Identifier
+     */
+    public static BGPPrefixLSIdentifier parsePrefixIdendifier(ChannelBuffer cb, byte protocolId)
+            throws BGPParseException {
+        //Parse Local Node descriptor
+        NodeDescriptors localNodeDescriptors = new NodeDescriptors();
+        localNodeDescriptors = parseLocalNodeDescriptors(cb, protocolId);
+
+        //Parse Prefix descriptor
+        LinkedList<BGPValueType> prefixDescriptor = new LinkedList<>();
+        prefixDescriptor = parsePrefixDescriptors(cb);
+        return new BGPPrefixLSIdentifier(localNodeDescriptors, prefixDescriptor);
+    }
+
+    /**
+     * Parse local node descriptors.
+     *
+     * @param cb ChannelBuffer
+     * @param protocolId protocol identifier
+     * @return LocalNodeDescriptors
+     * @throws BGPParseException while parsing local node descriptors
+     */
+    public static NodeDescriptors parseLocalNodeDescriptors(ChannelBuffer cb, byte protocolId)
+                                                                 throws BGPParseException {
+        ChannelBuffer tempBuf = cb;
+        short type = cb.readShort();
+        short length = cb.readShort();
+        if (cb.readableBytes() < length) {
+            //length + 4 implies data contains type, length and value
+            throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.OPTIONAL_ATTRIBUTE_ERROR,
+                    tempBuf.readBytes(cb.readableBytes() + TYPE_AND_LEN));
+        }
+        NodeDescriptors localNodeDescriptors = new NodeDescriptors();
+        ChannelBuffer tempCb = cb.readBytes(length);
+
+        if (type == NodeDescriptors.LOCAL_NODE_DES_TYPE) {
+            localNodeDescriptors = NodeDescriptors.read(tempCb, length, type, protocolId);
+        } else {
+            throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR,
+                                           BGPErrorType.MALFORMED_ATTRIBUTE_LIST, null);
+        }
+        return localNodeDescriptors;
+    }
+
+    /**
+     * Parse list of prefix descriptors.
+     *
+     * @param cb ChannelBuffer
+     * @return list of prefix descriptors
+     * @throws BGPParseException while parsing list of prefix descriptors
+     */
+    public static LinkedList<BGPValueType> parsePrefixDescriptors(ChannelBuffer cb) throws BGPParseException {
+        LinkedList<BGPValueType> prefixDescriptor = new LinkedList<>();
+        BGPValueType tlv = null;
+        boolean isIpReachInfo = false;
+        ChannelBuffer tempCb;
+        int count = 0;
+
+        while (cb.readableBytes() > 0) {
+            ChannelBuffer tempBuf = cb;
+            short type = cb.readShort();
+            short length = cb.readShort();
+            if (cb.readableBytes() < length) {
+                //length + 4 implies data contains type, length and value
+                throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.OPTIONAL_ATTRIBUTE_ERROR,
+                        tempBuf.readBytes(cb.readableBytes() + TYPE_AND_LEN));
+            }
+            tempCb = cb.readBytes(length);
+            switch (type) {
+            case OSPFRouteTypeTlv.TYPE:
+                tlv = OSPFRouteTypeTlv.read(tempCb);
+                break;
+            case IPReachabilityInformationTlv.TYPE:
+                tlv = IPReachabilityInformationTlv.read(tempCb, length);
+                isIpReachInfo = true;
+                break;
+            case BgpAttrNodeMultiTopologyId.ATTRNODE_MULTITOPOLOGY:
+                tlv = BgpAttrNodeMultiTopologyId.read(tempCb);
+                count = count + 1;
+                if (count > 1) {
+                    //length + 4 implies data contains type, length and value
+                    throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR,
+                           BGPErrorType.OPTIONAL_ATTRIBUTE_ERROR, tempBuf.readBytes(length + TYPE_AND_LEN));
+                }
+                break;
+            default:
+                UnSupportedAttribute.skipBytes(tempCb, length);
+            }
+            prefixDescriptor.add(tlv);
+        }
+
+        if (!isIpReachInfo) {
+            throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.OPTIONAL_ATTRIBUTE_ERROR,
+                    null);
+        }
+        return prefixDescriptor;
+    }
+
+    /**
+     * Returns local node descriptors.
+     *
+     * @return local node descriptors
+     */
+    public NodeDescriptors getLocalNodeDescriptors() {
+        return this.localNodeDescriptors;
+    }
+
+    /**
+     * Returns Prefix descriptors.
+     *
+     * @return Prefix descriptors
+     */
+    public LinkedList<BGPValueType> getPrefixdescriptor() {
+        return this.prefixDescriptor;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(prefixDescriptor.hashCode(), localNodeDescriptors);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof BGPPrefixLSIdentifier) {
+            int countObjSubTlv = 0;
+            int countOtherSubTlv = 0;
+            boolean isCommonSubTlv = true;
+            BGPPrefixLSIdentifier other = (BGPPrefixLSIdentifier) obj;
+
+            Iterator<BGPValueType> objListIterator = other.prefixDescriptor.iterator();
+            countOtherSubTlv = other.prefixDescriptor.size();
+            countObjSubTlv = prefixDescriptor.size();
+            if (countObjSubTlv != countOtherSubTlv) {
+                return false;
+            } else {
+                while (objListIterator.hasNext() && isCommonSubTlv) {
+                    BGPValueType subTlv = objListIterator.next();
+                    isCommonSubTlv = Objects.equals(prefixDescriptor.contains(subTlv),
+                            other.prefixDescriptor.contains(subTlv));
+                }
+                return isCommonSubTlv && Objects.equals(this.localNodeDescriptors, other.localNodeDescriptors);
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("localNodeDescriptors", localNodeDescriptors)
+                .add("prefixDescriptor", prefixDescriptor)
+                .toString();
+    }
+}
\ No newline at end of file
diff --git a/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/NodeDescriptors.java b/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/NodeDescriptors.java
new file mode 100644
index 0000000..a03b2ba
--- /dev/null
+++ b/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/NodeDescriptors.java
@@ -0,0 +1,225 @@
+/*
+ * 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.bgpio.protocol.link_state;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.bgpio.exceptions.BGPParseException;
+import org.onosproject.bgpio.types.AreaIDTlv;
+import org.onosproject.bgpio.types.AutonomousSystemTlv;
+import org.onosproject.bgpio.types.BGPErrorType;
+import org.onosproject.bgpio.types.BGPLSIdentifierTlv;
+import org.onosproject.bgpio.types.BGPValueType;
+import org.onosproject.bgpio.types.IsIsNonPseudonode;
+import org.onosproject.bgpio.types.IsIsPseudonode;
+import org.onosproject.bgpio.types.OSPFNonPseudonode;
+import org.onosproject.bgpio.types.OSPFPseudonode;
+import org.onosproject.bgpio.util.UnSupportedAttribute;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides Local and Remote NodeDescriptors which contains Node Descriptor Sub-TLVs.
+ */
+public class NodeDescriptors {
+
+    /*
+     *Reference :draft-ietf-idr-ls-distribution-11
+          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
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+         |              Type             |             Length            |
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+         |                                                               |
+         //              Node Descriptor Sub-TLVs (variable)            //
+         |                                                               |
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+                   Figure : Local or Remote Node Descriptors TLV format
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(NodeDescriptors.class);
+
+    public static final short LOCAL_NODE_DES_TYPE = 256;
+    public static final short REMOTE_NODE_DES_TYPE = 257;
+    public static final short IGP_ROUTERID_TYPE = 515;
+    public static final short IS_IS_LEVEL_1_PROTOCOL_ID = 1;
+    public static final short IS_IS_LEVEL_2_PROTOCOL_ID = 2;
+    public static final short OSPF_V2_PROTOCOL_ID = 3;
+    public static final short OSPF_V3_PROTOCOL_ID = 6;
+    public static final int TYPE_AND_LEN = 4;
+    public static final int ISISNONPSEUDONODE_LEN = 6;
+    public static final int ISISPSEUDONODE_LEN = 7;
+    public static final int OSPFNONPSEUDONODE_LEN = 4;
+    public static final int OSPFPSEUDONODE_LEN = 8;
+    private LinkedList<BGPValueType> subTlvs;
+    private short deslength;
+    private short desType;
+
+    /**
+     * Resets parameters.
+     */
+    public NodeDescriptors() {
+        this.subTlvs = null;
+        this.deslength = 0;
+        this.desType = 0;
+    }
+
+    /**
+     * Constructor to initialize parameters.
+     *
+     * @param subTlvs list of subTlvs
+     * @param deslength Descriptors length
+     * @param desType local node descriptor or remote node descriptor type
+     */
+    public NodeDescriptors(LinkedList<BGPValueType> subTlvs, short deslength, short desType) {
+        this.subTlvs = subTlvs;
+        this.deslength = deslength;
+        this.desType = desType;
+    }
+
+    /**
+     * Returns list of subTlvs.
+     *
+     * @return subTlvs list of subTlvs
+     */
+    public LinkedList<BGPValueType> getSubTlvs() {
+        return subTlvs;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(subTlvs.hashCode());
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof NodeDescriptors) {
+            int countObjSubTlv = 0;
+            int countOtherSubTlv = 0;
+            boolean isCommonSubTlv = true;
+            NodeDescriptors other = (NodeDescriptors) obj;
+            Iterator<BGPValueType> objListIterator = other.subTlvs.iterator();
+            countOtherSubTlv = other.subTlvs.size();
+            countObjSubTlv = subTlvs.size();
+            if (countObjSubTlv != countOtherSubTlv) {
+                return false;
+            } else {
+                while (objListIterator.hasNext() && isCommonSubTlv) {
+                    BGPValueType subTlv = objListIterator.next();
+                    isCommonSubTlv = Objects.equals(subTlvs.contains(subTlv), other.subTlvs.contains(subTlv));
+                }
+                return isCommonSubTlv;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Reads node descriptors Sub-TLVs.
+     *
+     * @param cb ChannelBuffer
+     * @param desLength node descriptor length
+     * @param desType local node descriptor or remote node descriptor type
+     * @param protocolId protocol ID
+     * @return object of NodeDescriptors
+     * @throws BGPParseException while parsing node descriptors
+     */
+    public static NodeDescriptors read(ChannelBuffer cb, short desLength, short desType, byte protocolId)
+            throws BGPParseException {
+        LinkedList<BGPValueType> subTlvs;
+        subTlvs = new LinkedList<>();
+        BGPValueType tlv = null;
+
+        while (cb.readableBytes() > 0) {
+            ChannelBuffer tempBuf = cb;
+            short type = cb.readShort();
+            short length = cb.readShort();
+            if (cb.readableBytes() < length) {
+                throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.OPTIONAL_ATTRIBUTE_ERROR,
+                        tempBuf.readBytes(cb.readableBytes() + TYPE_AND_LEN));
+            }
+            ChannelBuffer tempCb = cb.readBytes(length);
+            switch (type) {
+            case AutonomousSystemTlv.TYPE:
+                tlv = AutonomousSystemTlv.read(tempCb);
+                break;
+            case BGPLSIdentifierTlv.TYPE:
+                tlv = BGPLSIdentifierTlv.read(tempCb);
+                break;
+            case AreaIDTlv.TYPE:
+                tlv = AreaIDTlv.read(tempCb);
+                break;
+            case IGP_ROUTERID_TYPE:
+                if (protocolId == IS_IS_LEVEL_1_PROTOCOL_ID || protocolId == IS_IS_LEVEL_2_PROTOCOL_ID) {
+                    if (length == ISISNONPSEUDONODE_LEN) {
+                        tlv = IsIsNonPseudonode.read(tempCb);
+                    } else if (length == ISISPSEUDONODE_LEN) {
+                        tlv = IsIsPseudonode.read(tempCb);
+                    }
+                } else if (protocolId == OSPF_V2_PROTOCOL_ID || protocolId == OSPF_V3_PROTOCOL_ID) {
+                    if (length == OSPFNONPSEUDONODE_LEN) {
+                        tlv = OSPFNonPseudonode.read(tempCb);
+                    } else if (length == OSPFPSEUDONODE_LEN) {
+                        tlv = OSPFPseudonode.read(tempCb);
+                    }
+                }
+                break;
+            default:
+                UnSupportedAttribute.skipBytes(tempCb, length);
+            }
+            subTlvs.add(tlv);
+        }
+        return new NodeDescriptors(subTlvs, desLength, desType);
+    }
+
+    /**
+     * Returns node descriptors length.
+     *
+     * @return node descriptors length
+     */
+    public short getLength() {
+        return this.deslength;
+    }
+
+    /**
+     * Returns node descriptors type.
+     *
+     * @return node descriptors type
+     */
+    public short getType() {
+        return this.desType;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("desType", desType)
+                .add("deslength", deslength)
+                .add("subTlvs", subTlvs)
+                .toString();
+    }
+}
\ No newline at end of file
