diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/lcaf/LispNatLcafAddress.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/lcaf/LispNatLcafAddress.java
new file mode 100644
index 0000000..6da6b42
--- /dev/null
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/types/lcaf/LispNatLcafAddress.java
@@ -0,0 +1,339 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.lisp.msg.types.lcaf;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import io.netty.buffer.ByteBuf;
+import org.onosproject.lisp.msg.exceptions.LispParseError;
+import org.onosproject.lisp.msg.exceptions.LispReaderException;
+import org.onosproject.lisp.msg.exceptions.LispWriterException;
+import org.onosproject.lisp.msg.types.LispAddressReader;
+import org.onosproject.lisp.msg.types.LispAddressWriter;
+import org.onosproject.lisp.msg.types.LispAfiAddress;
+
+import java.util.List;
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Network Address Translation (NAT) address class.
+ * <p>
+ * Instance ID type is defined in draft-ietf-lisp-lcaf-22
+ * https://tools.ietf.org/html/draft-ietf-lisp-lcaf-22#page-12
+ *
+ * <pre>
+ * {@literal
+ *  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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |           AFI = 16387         |     Rsvd1     |     Flags     |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |   Type = 7    |     Rsvd2     |             Length            |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |       MS UDP Port Number      |      ETR UDP Port Number      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |              AFI = x          |  Global ETR RLOC Address  ... |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |              AFI = x          |       MS RLOC Address  ...    |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |              AFI = x          | Private ETR RLOC Address  ... |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |              AFI = x          |      RTR RLOC Address 1 ...   |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |              AFI = x          |      RTR RLOC Address k ...   |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * }</pre>
+ */
+public final class LispNatLcafAddress extends LispLcafAddress {
+
+    private final short msUdpPortNumber;
+    private final short etrUdpPortNumber;
+    private final LispAfiAddress globalEtrRlocAddress;
+    private final LispAfiAddress msRlocAddress;
+    private final LispAfiAddress privateEtrRlocAddress;
+    private final List<LispAfiAddress> rtrRlocAddresses;
+
+    /**
+     * Initializes NAT type LCAF address.
+     *
+     * @param reserved2             reserved2
+     * @param length                length
+     * @param msUdpPortNumber       Map Server (MS) UDP port number
+     * @param etrUdpPortNumber      ETR UDP port number
+     * @param globalEtrRlocAddress  global ETR RLOC address
+     * @param msRlocAddress         Map Server (MS) RLOC address
+     * @param privateEtrRlocAddress private ETR RLOC address
+     * @param rtrRlocAddresses      a collection of RTR RLOC addresses
+     */
+    private LispNatLcafAddress(byte reserved2, short length, short msUdpPortNumber,
+                               short etrUdpPortNumber, LispAfiAddress globalEtrRlocAddress,
+                               LispAfiAddress msRlocAddress, LispAfiAddress privateEtrRlocAddress,
+                               List<LispAfiAddress> rtrRlocAddresses) {
+        super(LispCanonicalAddressFormatEnum.NAT, reserved2, length);
+        this.msUdpPortNumber = msUdpPortNumber;
+        this.etrUdpPortNumber = etrUdpPortNumber;
+        this.globalEtrRlocAddress = globalEtrRlocAddress;
+        this.msRlocAddress = msRlocAddress;
+        this.privateEtrRlocAddress = privateEtrRlocAddress;
+        this.rtrRlocAddresses = ImmutableList.copyOf(rtrRlocAddresses);
+    }
+
+    /**
+     * Obtains Map Server UDP port number.
+     *
+     * @return Map Server UDP port number
+     */
+    public short getMsUdpPortNumber() {
+        return msUdpPortNumber;
+    }
+
+    /**
+     * Obtains ETR UDP port number.
+     *
+     * @return ETR UDP port number
+     */
+    public short getEtrUdpPortNumber() {
+        return etrUdpPortNumber;
+    }
+
+    /**
+     * Obtains global ETR RLOC address.
+     *
+     * @return global ETR
+     */
+    public LispAfiAddress getGlobalEtrRlocAddress() {
+        return globalEtrRlocAddress;
+    }
+
+    /**
+     * Obtains Map Server RLOC address.
+     *
+     * @return Map Server RLOC address
+     */
+    public LispAfiAddress getMsRlocAddress() {
+        return msRlocAddress;
+    }
+
+    /**
+     * Obtains private ETR RLOC address.
+     *
+     * @return private ETR RLOC address
+     */
+    public LispAfiAddress getPrivateEtrRlocAddress() {
+        return privateEtrRlocAddress;
+    }
+
+    /**
+     * Obtains a collection of RTR RLOC addresses.
+     *
+     * @return a collection of RTR RLOC addresses
+     */
+    public List<LispAfiAddress> getRtrRlocAddresses() {
+        return ImmutableList.copyOf(rtrRlocAddresses);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(msUdpPortNumber, etrUdpPortNumber,
+                globalEtrRlocAddress, msRlocAddress, privateEtrRlocAddress);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof LispNatLcafAddress) {
+            final LispNatLcafAddress other = (LispNatLcafAddress) obj;
+            return Objects.equals(this.msUdpPortNumber, other.msUdpPortNumber) &&
+                    Objects.equals(this.etrUdpPortNumber, other.etrUdpPortNumber) &&
+                    Objects.equals(this.globalEtrRlocAddress, other.globalEtrRlocAddress) &&
+                    Objects.equals(this.msRlocAddress, other.msRlocAddress) &&
+                    Objects.equals(this.privateEtrRlocAddress, other.privateEtrRlocAddress) &&
+                    Objects.equals(this.rtrRlocAddresses, other.rtrRlocAddresses);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this)
+                .add("Map Server UDP port number", msUdpPortNumber)
+                .add("ETR UDP port number", etrUdpPortNumber)
+                .add("global ETR RLOC address", globalEtrRlocAddress)
+                .add("Map Server RLOC address", msRlocAddress)
+                .add("private ETR RLOC address", privateEtrRlocAddress)
+                .add("RTR RLOC addresses", rtrRlocAddresses)
+                .toString();
+    }
+
+    public static final class NatAddressBuilder extends LcafAddressBuilder<NatAddressBuilder> {
+
+        private short msUdpPortNumber;
+        private short etrUdpPortNumber;
+        private LispAfiAddress globalEtrRlocAddress;
+        private LispAfiAddress msRlocAddress;
+        private LispAfiAddress privateEtrRlocAddress;
+        private List<LispAfiAddress> rtrRlocAddresses = Lists.newArrayList();
+
+        /**
+         * Sets Map Server UDP port number.
+         *
+         * @param msUdpPortNumber Map Server UDP port number
+         * @return NatAddressBuilder object
+         */
+        public NatAddressBuilder withMsUdpPortNumber(short msUdpPortNumber) {
+            this.msUdpPortNumber = msUdpPortNumber;
+            return this;
+        }
+
+        /**
+         * Sets ETR UDP port number.
+         *
+         * @param etrUdpPortNumber ETR UDP port number
+         * @return NatAddressBuilder object
+         */
+        public NatAddressBuilder withEtrUdpPortNumber(short etrUdpPortNumber) {
+            this.etrUdpPortNumber = etrUdpPortNumber;
+            return this;
+        }
+
+        /**
+         * Sets global ETR RLOC address.
+         *
+         * @param globalEtrRlocAddress global ETR RLOC address
+         * @return NatAddressBuilder object
+         */
+        public NatAddressBuilder withGlobalEtrRlocAddress(LispAfiAddress globalEtrRlocAddress) {
+            this.globalEtrRlocAddress = globalEtrRlocAddress;
+            return this;
+        }
+
+        /**
+         * Sets Map Server RLOC address.
+         *
+         * @param msRlocAddress Map Server RLOC address
+         * @return NatAddressBuilder object
+         */
+        public NatAddressBuilder withMsRlocAddress(LispAfiAddress msRlocAddress) {
+            this.msRlocAddress = msRlocAddress;
+            return this;
+        }
+
+        /**
+         * Sets private ETR RLOC address.
+         *
+         * @param privateEtrRlocAddress private ETR RLOC address
+         * @return NatAddressBuilder object
+         */
+        public NatAddressBuilder withPrivateEtrRlocAddress(LispAfiAddress privateEtrRlocAddress) {
+            this.privateEtrRlocAddress = privateEtrRlocAddress;
+            return this;
+        }
+
+        /**
+         * Sets RTR RLOC addresses.
+         *
+         * @param rtrRlocAddresses a collection of RTR RLOC addresses
+         * @return NatAddressBuilder object
+         */
+        public NatAddressBuilder withRtrRlocAddresses(List<LispAfiAddress> rtrRlocAddresses) {
+            if (rtrRlocAddresses != null) {
+                this.rtrRlocAddresses = ImmutableList.copyOf(rtrRlocAddresses);
+            }
+            return this;
+        }
+
+        public LispNatLcafAddress build() {
+
+            // TODO: need to do null check
+
+            return new LispNatLcafAddress(reserved2, length, msUdpPortNumber,
+                    etrUdpPortNumber, globalEtrRlocAddress, msRlocAddress,
+                    privateEtrRlocAddress, rtrRlocAddresses);
+        }
+    }
+
+    /**
+     * NAT LCAF address reader class.
+     */
+    public static class NatLcafAddressReader
+            implements LispAddressReader<LispNatLcafAddress> {
+
+        @Override
+        public LispNatLcafAddress readFrom(ByteBuf byteBuf)
+                throws LispParseError, LispReaderException {
+
+            LispLcafAddress lcafAddress = deserializeCommon(byteBuf);
+
+            short msUdpPortNumber = (short) byteBuf.readUnsignedShort();
+            short etrUdpPortNumber = (short) byteBuf.readUnsignedShort();
+
+            LispAfiAddress globalEtrRlocAddress = new AfiAddressReader().readFrom(byteBuf);
+            LispAfiAddress msRlocAddress = new AfiAddressReader().readFrom(byteBuf);
+            LispAfiAddress privateEtrRlocAddress = new AfiAddressReader().readFrom(byteBuf);
+
+            List<LispAfiAddress> rtrRlocAddresses = Lists.newArrayList();
+
+            while (byteBuf.readerIndex() - COMMON_HEADER_SIZE < lcafAddress.getLength()) {
+                rtrRlocAddresses.add(new AfiAddressReader().readFrom(byteBuf));
+            }
+
+            return new NatAddressBuilder()
+                            .withMsUdpPortNumber(msUdpPortNumber)
+                            .withEtrUdpPortNumber(etrUdpPortNumber)
+                            .withGlobalEtrRlocAddress(globalEtrRlocAddress)
+                            .withMsRlocAddress(msRlocAddress)
+                            .withPrivateEtrRlocAddress(privateEtrRlocAddress)
+                            .withRtrRlocAddresses(rtrRlocAddresses)
+                            .build();
+        }
+    }
+
+    /**
+     * NAT LCAF address writer class.
+     */
+    public static class NatLcafAddressWriter
+            implements LispAddressWriter<LispNatLcafAddress> {
+
+        @Override
+        public void writeTo(ByteBuf byteBuf, LispNatLcafAddress address)
+                throws LispWriterException {
+
+            int lcafIndex = byteBuf.writerIndex();
+            serializeCommon(byteBuf, address);
+
+            byteBuf.writeShort(address.getMsUdpPortNumber());
+            byteBuf.writeShort(address.getEtrUdpPortNumber());
+
+            AfiAddressWriter writer = new LispAfiAddress.AfiAddressWriter();
+            writer.writeTo(byteBuf, address.getGlobalEtrRlocAddress());
+            writer.writeTo(byteBuf, address.getMsRlocAddress());
+            writer.writeTo(byteBuf, address.getPrivateEtrRlocAddress());
+
+            List<LispAfiAddress> rtrRlocAddresses = address.getRtrRlocAddresses();
+
+            for (int i = 0; i < rtrRlocAddresses.size(); i++) {
+                writer.writeTo(byteBuf, rtrRlocAddresses.get(i));
+            }
+
+            updateLength(lcafIndex, byteBuf);
+        }
+    }
+}
