diff --git a/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/tlvtypes/LinkTlv.java b/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/tlvtypes/LinkTlv.java
new file mode 100644
index 0000000..aaf66da
--- /dev/null
+++ b/protocols/ospf/protocol/src/main/java/org/onosproject/ospf/protocol/lsa/tlvtypes/LinkTlv.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright 2016 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.ospf.protocol.lsa.tlvtypes;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.primitives.Bytes;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.ospf.protocol.lsa.TlvHeader;
+import org.onosproject.ospf.protocol.lsa.linksubtype.AdministrativeGroup;
+import org.onosproject.ospf.protocol.lsa.linksubtype.LinkId;
+import org.onosproject.ospf.protocol.lsa.linksubtype.LinkSubType;
+import org.onosproject.ospf.protocol.lsa.linksubtype.LinkSubTypes;
+import org.onosproject.ospf.protocol.lsa.linksubtype.LinkType;
+import org.onosproject.ospf.protocol.lsa.linksubtype.LocalInterfaceIpAddress;
+import org.onosproject.ospf.protocol.lsa.linksubtype.MaximumBandwidth;
+import org.onosproject.ospf.protocol.lsa.linksubtype.MaximumReservableBandwidth;
+import org.onosproject.ospf.protocol.lsa.linksubtype.RemoteInterfaceIpAddress;
+import org.onosproject.ospf.protocol.lsa.linksubtype.TrafficEngineeringMetric;
+import org.onosproject.ospf.protocol.lsa.linksubtype.UnknownLinkSubType;
+import org.onosproject.ospf.protocol.lsa.linksubtype.UnreservedBandwidth;
+import org.onosproject.ospf.protocol.lsa.types.TopLevelTlv;
+import org.onosproject.ospf.protocol.util.OspfUtil;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Representation of an OSPF Opaque link tlv.
+ */
+public class LinkTlv extends TlvHeader implements TopLevelTlv {
+    private List<LinkSubType> subTlv = new ArrayList<>();
+
+    /**
+     * Creates an instance of link tlv.
+     *
+     * @param header tlv header
+     */
+    public LinkTlv(TlvHeader header) {
+        this.setTlvType(header.tlvType());
+        this.setTlvLength(header.tlvLength());
+    }
+
+    /**
+     * Gets sub tlv lists.
+     *
+     * @return sub tlv lists
+     */
+    public List<LinkSubType> subTlvList() {
+        return this.subTlv;
+    }
+
+    /**
+     * Reads bytes from channel buffer .
+     *
+     * @param channelBuffer channel buffer instance
+     * @throws Exception might throws exception while parsing packet
+     */
+    public void readFrom(ChannelBuffer channelBuffer) throws Exception {
+        while (channelBuffer.readableBytes() > 0) {
+            TlvHeader tlvHeader = new TlvHeader();
+            tlvHeader.setTlvType(channelBuffer.readUnsignedShort());
+            tlvHeader.setTlvLength(channelBuffer.readUnsignedShort());
+
+            if (LinkSubTypes.LINK_TYPE.value() == tlvHeader.tlvType()) {
+                LinkType linktype = new LinkType(tlvHeader);
+                linktype.readFrom(channelBuffer.readBytes(tlvHeader.tlvLength()));
+                subTlv.add(linktype);
+                if (tlvHeader.tlvLength() < OspfUtil.FOUR_BYTES) {
+                    int readerIndex = channelBuffer.readerIndex() + (OspfUtil.FOUR_BYTES - tlvHeader.tlvLength());
+                    channelBuffer.readerIndex(readerIndex);
+                }
+            } else if (LinkSubTypes.LINK_ID.value() == tlvHeader.tlvType()) {
+                LinkId linkId = new LinkId(tlvHeader);
+                linkId.readFrom(channelBuffer.readBytes(tlvHeader.tlvLength()));
+                subTlv.add(linkId);
+            } else if (LinkSubTypes.LOCAL_INTERFACE_IP_ADDRESS.value() == tlvHeader.tlvType()) {
+                LocalInterfaceIpAddress localInterfaceIpAddress = new LocalInterfaceIpAddress(tlvHeader);
+                localInterfaceIpAddress.readFrom(channelBuffer.readBytes(tlvHeader.tlvLength()));
+                subTlv.add(localInterfaceIpAddress);
+            } else if (LinkSubTypes.REMOTE_INTERFACE_IP_ADDRESS.value() == tlvHeader.tlvType()) {
+                RemoteInterfaceIpAddress remoteInterfaceIpAddress = new RemoteInterfaceIpAddress(tlvHeader);
+                remoteInterfaceIpAddress.readFrom(channelBuffer.readBytes(tlvHeader.tlvLength()));
+                subTlv.add(remoteInterfaceIpAddress);
+            } else if (LinkSubTypes.TRAFFIC_ENGINEERING_METRIC.value() == tlvHeader.tlvType()) {
+                TrafficEngineeringMetric trafficEngineeringMetric = new TrafficEngineeringMetric(tlvHeader);
+                trafficEngineeringMetric.readFrom(channelBuffer.readBytes(tlvHeader.tlvLength()));
+                subTlv.add(trafficEngineeringMetric);
+            } else if (LinkSubTypes.MAXIMUM_BANDWIDTH.value() == tlvHeader.tlvType()) {
+                MaximumBandwidth maximumBandwidth = new MaximumBandwidth(tlvHeader);
+                maximumBandwidth.readFrom(channelBuffer.readBytes(tlvHeader.tlvLength()));
+                subTlv.add(maximumBandwidth);
+            } else if (LinkSubTypes.MAXIMUM_RESERVABLE_BANDWIDTH.value() == tlvHeader.tlvType()) {
+                MaximumReservableBandwidth maximumReservableBandwidth = new MaximumReservableBandwidth(tlvHeader);
+                maximumReservableBandwidth.readFrom(channelBuffer.readBytes(tlvHeader.tlvLength()));
+                subTlv.add(maximumReservableBandwidth);
+            } else if (LinkSubTypes.UNRESERVED_BANDWIDTH.value() == tlvHeader.tlvType()) {
+                UnreservedBandwidth unreservedBandwidth = new UnreservedBandwidth(tlvHeader);
+                unreservedBandwidth.readFrom(channelBuffer.readBytes(tlvHeader.tlvLength()));
+                subTlv.add(unreservedBandwidth);
+            } else if (LinkSubTypes.ADMINISTRATIVE_GROUP.value() == tlvHeader.tlvType()) {
+                AdministrativeGroup administrativeGroup = new AdministrativeGroup(tlvHeader);
+                administrativeGroup.readFrom(channelBuffer.readBytes(tlvHeader.tlvLength()));
+                subTlv.add(administrativeGroup);
+            } else {
+                UnknownLinkSubType unknownLinkSubType = new UnknownLinkSubType(tlvHeader);
+                unknownLinkSubType.readFrom(channelBuffer.readBytes(tlvHeader.tlvLength()));
+                subTlv.add(unknownLinkSubType);
+            }
+        }
+    }
+
+    /**
+     * Gets link tlv as byte array.
+     *
+     * @return link tlv as byte array
+     * @throws Exception might throws exception while parsing buffer
+     */
+    public byte[] asBytes() throws Exception {
+        byte[] lsaMessage = null;
+
+        byte[] tlvHeader = getTlvHeaderAsByteArray();
+        byte[] tlvBody = getTlvBodyAsByteArray();
+        lsaMessage = Bytes.concat(tlvHeader, tlvBody);
+
+        return lsaMessage;
+    }
+
+    /**
+     * Gets tlv body as byte array.
+     *
+     * @return tlv body as byte array
+     * @throws Exception might throws exception while parsing buffer
+     */
+    public byte[] getTlvBodyAsByteArray() throws Exception {
+
+        List<Byte> bodyLst = new ArrayList<>();
+        for (LinkSubType tlv : subTlv) {
+            //Check the type of tlv and build bytes accordingly
+            if (tlv instanceof LinkType) {
+                LinkType linkType = (LinkType) tlv;
+                bodyLst.addAll(Bytes.asList(linkType.asBytes()));
+            } else if (tlv instanceof LinkId) {
+                LinkId linkId = (LinkId) tlv;
+                bodyLst.addAll(Bytes.asList(linkId.asBytes()));
+            } else if (tlv instanceof LocalInterfaceIpAddress) {
+                LocalInterfaceIpAddress localInterfaceIpAddress = (LocalInterfaceIpAddress) tlv;
+                bodyLst.addAll(Bytes.asList(localInterfaceIpAddress.asBytes()));
+            } else if (tlv instanceof RemoteInterfaceIpAddress) {
+                RemoteInterfaceIpAddress remoteInterfaceIpAddress = (RemoteInterfaceIpAddress) tlv;
+                bodyLst.addAll(Bytes.asList(remoteInterfaceIpAddress.asBytes()));
+            } else if (tlv instanceof TrafficEngineeringMetric) {
+                TrafficEngineeringMetric trafficEngineeringMetric = (TrafficEngineeringMetric) tlv;
+                bodyLst.addAll(Bytes.asList(trafficEngineeringMetric.asBytes()));
+            } else if (tlv instanceof MaximumBandwidth) {
+                MaximumBandwidth maximumBandwidth = (MaximumBandwidth) tlv;
+                bodyLst.addAll(Bytes.asList(maximumBandwidth.asBytes()));
+            } else if (tlv instanceof MaximumReservableBandwidth) {
+                MaximumReservableBandwidth maximumReservableBandwidth = (MaximumReservableBandwidth) tlv;
+                bodyLst.addAll(Bytes.asList(maximumReservableBandwidth.asBytes()));
+            } else if (tlv instanceof UnreservedBandwidth) {
+                UnreservedBandwidth unreservedBandwidth = (UnreservedBandwidth) tlv;
+                bodyLst.addAll(Bytes.asList(unreservedBandwidth.asBytes()));
+            } else if (tlv instanceof AdministrativeGroup) {
+                AdministrativeGroup administrativeGroup = (AdministrativeGroup) tlv;
+                bodyLst.addAll(Bytes.asList(administrativeGroup.asBytes()));
+            } else {
+                UnknownLinkSubType unknownLinkSubType = (UnknownLinkSubType) tlv;
+                bodyLst.addAll(Bytes.asList(unknownLinkSubType.asBytes()));
+            }
+        }
+        return Bytes.toArray(bodyLst);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .omitNullValues()
+                .add("subTlv", subTlv)
+                .toString();
+    }
+}
\ No newline at end of file
