diff --git a/providers/lisp/mapping/src/main/java/org/onosproject/provider/lisp/mapping/impl/LispMappingProvider.java b/providers/lisp/mapping/src/main/java/org/onosproject/provider/lisp/mapping/impl/LispMappingProvider.java
index 05e5dd7..3cf1e3b 100644
--- a/providers/lisp/mapping/src/main/java/org/onosproject/provider/lisp/mapping/impl/LispMappingProvider.java
+++ b/providers/lisp/mapping/src/main/java/org/onosproject/provider/lisp/mapping/impl/LispMappingProvider.java
@@ -25,12 +25,14 @@
 import org.onosproject.lisp.ctl.LispRouterId;
 import org.onosproject.lisp.ctl.LispRouterListener;
 import org.onosproject.lisp.msg.protocols.LispMapNotify;
+import org.onosproject.lisp.msg.protocols.LispMapRecord;
 import org.onosproject.lisp.msg.protocols.LispMapReply;
 import org.onosproject.lisp.msg.protocols.LispMessage;
 import org.onosproject.mapping.MappingEntry;
 import org.onosproject.mapping.MappingProvider;
 import org.onosproject.mapping.MappingProviderRegistry;
 import org.onosproject.mapping.MappingProviderService;
+import org.onosproject.mapping.MappingStore;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.provider.AbstractProvider;
 import org.onosproject.net.provider.ProviderId;
@@ -38,6 +40,8 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.List;
+
 import static org.onosproject.mapping.MappingStore.Type.MAP_CACHE;
 import static org.onosproject.mapping.MappingStore.Type.MAP_DATABASE;
 
@@ -138,21 +142,33 @@
 
                 case LISP_MAP_REPLY:
                     LispMapReply reply = (LispMapReply) msg;
-
-                    MappingEntry replyMe = new MappingEntryBuilder(deviceId, reply).build();
-                    providerService.mappingAdded(replyMe, MAP_CACHE);
+                    processMappings(deviceId, reply.getMapRecords(), MAP_CACHE);
                     break;
 
                 case LISP_MAP_NOTIFY:
                     LispMapNotify notify = (LispMapNotify) msg;
-
-                    MappingEntry notifyMe = new MappingEntryBuilder(deviceId, notify).build();
-                    providerService.mappingAdded(notifyMe, MAP_DATABASE);
+                    processMappings(deviceId, notify.getMapRecords(), MAP_DATABASE);
                     break;
 
                 default:
                     log.warn("Unhandled message type: {}", msg.getType());
             }
         }
+
+        /**
+         * Converts map records into mapping, notifies to provider.
+         *
+         * @param deviceId device identifier
+         * @param records  a collection of map records
+         * @param type     MappingStore type
+         */
+        private void processMappings(DeviceId deviceId,
+                                     List<LispMapRecord> records,
+                                     MappingStore.Type type) {
+            records.forEach(r -> {
+                MappingEntry me = new MappingEntryBuilder(deviceId, r).build();
+                providerService.mappingAdded(me, type);
+            });
+        }
     }
 }
diff --git a/providers/lisp/mapping/src/main/java/org/onosproject/provider/lisp/mapping/util/MappingEntryBuilder.java b/providers/lisp/mapping/src/main/java/org/onosproject/provider/lisp/mapping/util/MappingEntryBuilder.java
index 12a58e4..90052c28 100644
--- a/providers/lisp/mapping/src/main/java/org/onosproject/provider/lisp/mapping/util/MappingEntryBuilder.java
+++ b/providers/lisp/mapping/src/main/java/org/onosproject/provider/lisp/mapping/util/MappingEntryBuilder.java
@@ -15,49 +15,246 @@
  */
 package org.onosproject.provider.lisp.mapping.util;
 
-import org.onosproject.lisp.msg.protocols.LispMapNotify;
-import org.onosproject.lisp.msg.protocols.LispMapReply;
+import com.google.common.collect.Lists;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onosproject.lisp.msg.protocols.LispLocator;
+import org.onosproject.lisp.msg.protocols.LispMapRecord;
+import org.onosproject.lisp.msg.types.LispAfiAddress;
+import org.onosproject.lisp.msg.types.LispAsAddress;
+import org.onosproject.lisp.msg.types.LispDistinguishedNameAddress;
+import org.onosproject.lisp.msg.types.LispIpv4Address;
+import org.onosproject.lisp.msg.types.LispIpv6Address;
+import org.onosproject.lisp.msg.types.LispMacAddress;
+import org.onosproject.mapping.DefaultMapping;
+import org.onosproject.mapping.DefaultMappingEntry;
+import org.onosproject.mapping.DefaultMappingKey;
+import org.onosproject.mapping.DefaultMappingTreatment;
+import org.onosproject.mapping.DefaultMappingValue;
+import org.onosproject.mapping.Mapping;
 import org.onosproject.mapping.MappingEntry;
+import org.onosproject.mapping.MappingEntry.MappingEntryState;
+import org.onosproject.mapping.MappingKey;
+import org.onosproject.mapping.MappingTreatment;
+import org.onosproject.mapping.MappingValue;
+import org.onosproject.mapping.actions.MappingAction;
+import org.onosproject.mapping.actions.MappingActions;
+import org.onosproject.mapping.addresses.MappingAddress;
+import org.onosproject.mapping.addresses.MappingAddresses;
 import org.onosproject.net.DeviceId;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.List;
+import java.util.UUID;
+
+import static org.onosproject.lisp.msg.types.AddressFamilyIdentifierEnum.IP4;
+import static org.onosproject.lisp.msg.types.AddressFamilyIdentifierEnum.IP6;
+
 /**
  * Mapping entry builder class.
  */
 public class MappingEntryBuilder {
-    private static final Logger log = LoggerFactory.getLogger(MappingEntryBuilder.class);
+    private static final Logger log =
+                            LoggerFactory.getLogger(MappingEntryBuilder.class);
+
+    private static final int IPV4_PREFIX_LENGTH = 32;
+    private static final int IPV6_PREFIX_LENGTH = 128;
 
     private final DeviceId deviceId;
-    private final LispMapReply mapReply;
-    private final LispMapNotify mapNotify;
+
+    private final MappingAddress address;
+    private final MappingAction action;
+    private final List<MappingTreatment> treatments;
 
     /**
      * Default constructor for MappingEntryBuilder.
      *
      * @param deviceId device identifier
-     * @param mapReply map reply message
+     * @param record   LISP map record
      */
-    public MappingEntryBuilder(DeviceId deviceId, LispMapReply mapReply) {
+    public MappingEntryBuilder(DeviceId deviceId, LispMapRecord record) {
         this.deviceId = deviceId;
-        this.mapReply = mapReply;
-        this.mapNotify = null;
+        this.address = buildAddress(record);
+        this.action = buildAction(record);
+        this.treatments = buildTreatments(record);
     }
 
     /**
-     * Default constructor for MappingEntryBuilder.
+     * Builds mapping entry from a specific LISP control message.
      *
-     * @param deviceId  device identifier
-     * @param mapNotify map notify message
+     * @return mapping entry
      */
-    public MappingEntryBuilder(DeviceId deviceId, LispMapNotify mapNotify) {
-        this.deviceId = deviceId;
-        this.mapNotify = mapNotify;
-        this.mapReply = null;
+    public MappingEntry build() {
+        Mapping.Builder builder;
+
+        // we assign leastSignificantBits of UUID as the mapping identifier for now
+        // id generation scheme can be changed later
+        UUID uuid = UUID.randomUUID();
+
+        builder = DefaultMapping.builder()
+                .withId(uuid.getLeastSignificantBits())
+                .forDevice(deviceId)
+                .withKey(buildKey())
+                .withValue(buildValue());
+
+        // TODO: we assume that the mapping entry will be always
+        // stored in routers without failure for now, which means
+        // the mapping entry state will always be ADDED rather than
+        // PENDING_ADD
+        // we will revisit this part when LISP driver is finished
+        return new DefaultMappingEntry(builder.build(), MappingEntryState.ADDED);
     }
 
-    public MappingEntry build() {
-        // TODO: provide a way to build mapping entry from input parameters
+    /**
+     * Builds mapping key.
+     *
+     * @return mapping key
+     */
+    private MappingKey buildKey() {
+
+        MappingKey.Builder builder = DefaultMappingKey.builder();
+
+        builder.withAddress(address);
+
+        return builder.build();
+    }
+
+    /**
+     * Builds mapping value.
+     *
+     * @return mapping value
+     */
+    private MappingValue buildValue() {
+
+        MappingValue.Builder builder = DefaultMappingValue.builder();
+        builder.withAction(action);
+
+        treatments.forEach(builder::add);
+
+        return builder.build();
+    }
+
+    /**
+     * Builds mapping action.
+     *
+     * @param record LISP map record
+     * @return mapping action
+     */
+    private MappingAction buildAction(LispMapRecord record) {
+
+        if (record == null) {
+            return MappingActions.noAction();
+        }
+
+        switch (record.getAction()) {
+            case NoAction:
+                return MappingActions.noAction();
+            case SendMapRequest:
+                return MappingActions.forward();
+            case NativelyForward:
+                return MappingActions.nativeForward();
+            case Drop:
+                return MappingActions.drop();
+            default:
+                log.warn("Unsupported action type {}", record.getAction());
+                return MappingActions.noAction();
+        }
+    }
+
+    /**
+     * Builds mapping address.
+     *
+     * @param record LISP map record
+     * @return mapping address
+     */
+    private MappingAddress buildAddress(LispMapRecord record) {
+
+        return record == null ? null :
+                getAddress(record.getEidPrefixAfi(), record.getMaskLength());
+    }
+
+    /**
+     * Converts LispAfiAddress into abstracted mapping address.
+     *
+     * @param address LispAfiAddress
+     * @param length  mask length
+     * @return abstracted mapping address
+     */
+    private MappingAddress getAddress(LispAfiAddress address, int length) {
+
+        if (address == null) {
+            log.warn("Address is not specified.");
+            return null;
+        }
+
+        switch (address.getAfi()) {
+            case IP4:
+                IpAddress ipv4Address = ((LispIpv4Address) address).getAddress();
+                IpPrefix ipv4Prefix = IpPrefix.valueOf(ipv4Address, length);
+                return MappingAddresses.ipv4MappingAddress(ipv4Prefix);
+            case IP6:
+                IpAddress ipv6Address = ((LispIpv6Address) address).getAddress();
+                IpPrefix ipv6Prefix = IpPrefix.valueOf(ipv6Address, length);
+                return MappingAddresses.ipv6MappingAddress(ipv6Prefix);
+            case AS:
+                int asNum = ((LispAsAddress) address).getASNum();
+                return MappingAddresses.asMappingAddress(String.valueOf(asNum));
+            case DISTINGUISHED_NAME:
+                String dn = ((LispDistinguishedNameAddress)
+                                                address).getDistinguishedName();
+                return MappingAddresses.dnMappingAddress(dn);
+            case MAC:
+                MacAddress macAddress = ((LispMacAddress) address).getAddress();
+                return MappingAddresses.ethMappingAddress(macAddress);
+            case LCAF:
+                // TODO: need to use extension address to abstract LCAF address
+                break;
+            default:
+                log.warn("Unsupported address type {}", address.getAfi());
+                break;
+        }
+
         return null;
     }
+
+    /**
+     * Builds a collection of mapping treatments.
+     *
+     * @param record LISP map record
+     * @return a collection of mapping treatments
+     */
+    private List<MappingTreatment> buildTreatments(LispMapRecord record) {
+
+        List<LispLocator> locators = record.getLocators();
+        List<MappingTreatment> treatments = Lists.newArrayList();
+        for (LispLocator locator : locators) {
+            MappingTreatment.Builder builder = DefaultMappingTreatment.builder();
+            LispAfiAddress address = locator.getLocatorAfi();
+            int addressLength = 0;
+            if (address.getAfi() == IP4) {
+                addressLength = IPV4_PREFIX_LENGTH;
+            } else if (address.getAfi() == IP6) {
+                addressLength = IPV6_PREFIX_LENGTH;
+            }
+
+            final MappingAddress mappingAddress = getAddress(address, addressLength);
+            if (mappingAddress != null) {
+                builder.withAddress(mappingAddress);
+            }
+
+            builder.setUnicastWeight(locator.getWeight())
+                    .setUnicastPriority(locator.getPriority())
+                    .setMulticastWeight(locator.getMulticastWeight())
+                    .setMulticastPriority(locator.getMulticastPriority());
+
+            // TODO: need to convert specific properties to
+            // abstracted extension properties
+
+            treatments.add(builder.build());
+        }
+
+        return treatments;
+    }
 }
diff --git a/providers/lisp/mapping/src/test/java/org/onosproject/provider/lisp/mapping/util/MappingEntryBuilderTest.java b/providers/lisp/mapping/src/test/java/org/onosproject/provider/lisp/mapping/util/MappingEntryBuilderTest.java
new file mode 100644
index 0000000..c6bf5fa
--- /dev/null
+++ b/providers/lisp/mapping/src/test/java/org/onosproject/provider/lisp/mapping/util/MappingEntryBuilderTest.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2017-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.provider.lisp.mapping.util;
+
+import com.google.common.collect.ImmutableList;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onosproject.lisp.msg.protocols.DefaultLispLocator.DefaultLocatorBuilder;
+import org.onosproject.lisp.msg.protocols.DefaultLispMapNotify.DefaultNotifyBuilder;
+import org.onosproject.lisp.msg.protocols.DefaultLispMapRecord.DefaultMapRecordBuilder;
+import org.onosproject.lisp.msg.protocols.DefaultLispMapReply.DefaultReplyBuilder;
+import org.onosproject.lisp.msg.protocols.LispLocator;
+import org.onosproject.lisp.msg.protocols.LispLocator.LocatorBuilder;
+import org.onosproject.lisp.msg.protocols.LispMapNotify;
+import org.onosproject.lisp.msg.protocols.LispMapNotify.NotifyBuilder;
+import org.onosproject.lisp.msg.protocols.LispMapRecord;
+import org.onosproject.lisp.msg.protocols.LispMapRecord.MapRecordBuilder;
+import org.onosproject.lisp.msg.protocols.LispMapReply;
+import org.onosproject.lisp.msg.protocols.LispMapReply.ReplyBuilder;
+import org.onosproject.lisp.msg.protocols.LispMapReplyAction;
+import org.onosproject.lisp.msg.types.LispIpv4Address;
+import org.onosproject.mapping.MappingEntry;
+import org.onosproject.mapping.MappingKey;
+import org.onosproject.mapping.MappingTreatment;
+import org.onosproject.mapping.MappingValue;
+import org.onosproject.mapping.actions.MappingAction;
+import org.onosproject.mapping.addresses.IPMappingAddress;
+import org.onosproject.net.DeviceId;
+
+import java.util.List;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+
+/**
+ * Mapping entry builder unit test.
+ */
+public class MappingEntryBuilderTest {
+
+    private static final String IP_RECORD_ADDRESS = "192.168.1.1";
+    private static final String IP_LOCATOR_ADDRESS = "10.1.1.1";
+    private static final int IP_RECORD_MASK_LENGTH = 24;
+    private static final int IP_LOCATOR_MASK_LENGTH = 32;
+
+    private static final String AUTH_KEY = "onos";
+
+    private static final byte UNIQUE_VALUE = (byte) 0x01;
+    private static final DeviceId DEVICE_ID = DeviceId.deviceId("lisp:10.1.1.2");
+
+    private LispMapReply mapReply;
+    private LispMapNotify mapNotify;
+
+    @Before
+    public void setUp() {
+        ReplyBuilder replyBuilder = new DefaultReplyBuilder();
+
+        List<LispMapRecord> records = ImmutableList.of(getMapRecord());
+
+        mapReply = replyBuilder
+                        .withIsEtr(true)
+                        .withIsProbe(false)
+                        .withIsSecurity(true)
+                        .withNonce(1L)
+                        .withMapRecords(records)
+                        .build();
+
+        NotifyBuilder notifyBuilder = new DefaultNotifyBuilder();
+
+        mapNotify = notifyBuilder
+                        .withKeyId((short) 1)
+                        .withAuthKey(AUTH_KEY)
+                        .withNonce(1L)
+                        .withMapRecords(records)
+                        .build();
+    }
+
+    @Test
+    public void testMapReplyConversion() {
+        List<LispMapRecord> replyRecords = mapReply.getMapRecords();
+
+        assertThat(replyRecords.size(), is(1));
+
+        testMapRecorConversion(replyRecords.get(0));
+    }
+
+    @Test
+    public void testMapNotifyConversion() {
+        List<LispMapRecord> notifyRecords = mapNotify.getMapRecords();
+
+        assertThat(notifyRecords.size(), is(1));
+
+        testMapRecorConversion(notifyRecords.get(0));
+    }
+
+    private void testMapRecorConversion(LispMapRecord record) {
+        MappingEntry mappingEntry =
+                     new MappingEntryBuilder(DEVICE_ID, record).build();
+        MappingKey key = mappingEntry.key();
+        MappingValue value = mappingEntry.value();
+
+        IPMappingAddress recordAddress = (IPMappingAddress) key.address();
+
+        assertThat(recordAddress.ip(), is(IpPrefix.valueOf(IP_RECORD_ADDRESS + "/" +
+                IP_RECORD_MASK_LENGTH)));
+
+        assertThat(value.action().type(), is(MappingAction.Type.NATIVE_FORWARD));
+
+        assertThat(value.treatments().size(), is(1));
+
+        MappingTreatment treatment = value.treatments().get(0);
+        IPMappingAddress locatorAddress = (IPMappingAddress) treatment.address();
+
+        assertThat(locatorAddress.ip(), is(IpPrefix.valueOf(IP_LOCATOR_ADDRESS + "/" +
+                IP_LOCATOR_MASK_LENGTH)));
+    }
+
+    private LispMapRecord getMapRecord() {
+        MapRecordBuilder recordBuilder = new DefaultMapRecordBuilder();
+
+        LispIpv4Address recordAddress =
+                        new LispIpv4Address(IpAddress.valueOf(IP_RECORD_ADDRESS));
+
+        LocatorBuilder locatorBuilder = new DefaultLocatorBuilder();
+
+        LispIpv4Address locatorAddress =
+                        new LispIpv4Address(IpAddress.valueOf(IP_LOCATOR_ADDRESS));
+
+        LispLocator locator1 = locatorBuilder
+                                    .withPriority(UNIQUE_VALUE)
+                                    .withWeight(UNIQUE_VALUE)
+                                    .withMulticastPriority(UNIQUE_VALUE)
+                                    .withMulticastWeight(UNIQUE_VALUE)
+                                    .withLocalLocator(true)
+                                    .withRlocProbed(false)
+                                    .withRouted(true)
+                                    .withLocatorAfi(locatorAddress)
+                                    .build();
+
+        return recordBuilder
+                .withRecordTtl(100)
+                .withIsAuthoritative(true)
+                .withMapVersionNumber((short) 1)
+                .withMaskLength((byte) IP_RECORD_MASK_LENGTH)
+                .withAction(LispMapReplyAction.NativelyForward)
+                .withEidPrefixAfi(recordAddress)
+                .withLocators(ImmutableList.of(locator1))
+                .build();
+    }
+}
