diff --git a/apps/cfm/src/main/java/org/onosproject/cfm/rest/MepWebResource.java b/apps/cfm/src/main/java/org/onosproject/cfm/rest/MepWebResource.java
new file mode 100644
index 0000000..fa8c728
--- /dev/null
+++ b/apps/cfm/src/main/java/org/onosproject/cfm/rest/MepWebResource.java
@@ -0,0 +1,346 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.cfm.rest;
+
+import java.io.InputStream;
+import java.net.URI;
+import java.util.Collection;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.onosproject.cfm.web.MepCodec;
+import org.onosproject.codec.JsonCodec;
+import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceAssociation;
+import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceDomain;
+import org.onosproject.incubator.net.l2monitoring.cfm.Mep;
+import org.onosproject.incubator.net.l2monitoring.cfm.MepEntry;
+import org.onosproject.incubator.net.l2monitoring.cfm.MepLbCreate;
+import org.onosproject.incubator.net.l2monitoring.cfm.MepLtCreate;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdCharStr;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdShort;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdCharStr;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
+import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmConfigException;
+import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMdService;
+import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMepService;
+import org.onosproject.rest.AbstractWebResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+/**
+ * Layer 2 CFM Maintenance Association Endpoint (MEP) web resource.
+ */
+@Path("md/{md_name}/ma/{ma_name}/mep")
+public class MepWebResource extends AbstractWebResource {
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    /**
+     * Get all MEPs by MD name, MA name.
+     *
+     * @param mdName The name of a Maintenance Domain
+     * @param maName The name of a Maintenance Association belonging to the MD
+     * @return 200 OK with a list of MEPS or 500 on error
+     */
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response getAllMepsForMa(@PathParam("md_name") String mdName,
+            @PathParam("ma_name") String maName) {
+        log.debug("GET all Meps called for MA {}", mdName + "/" + maName);
+        try {
+            MdId mdId = MdIdCharStr.asMdId(mdName);
+            MaIdShort maId = MaIdCharStr.asMaId(maName);
+            Collection<MepEntry> mepCollection = get(CfmMepService.class).getAllMeps(mdId, maId);
+            ArrayNode an = mapper().createArrayNode();
+            an.add(codec(MepEntry.class).encode(mepCollection, this));
+            return ok(mapper().createObjectNode().set("meps", an)).build();
+        } catch (CfmConfigException e) {
+            log.error("Get all Meps on {} failed because of exception",
+                    mdName + "/" + maName, e);
+            return Response.serverError().entity("{ \"failure\":\"" + e.toString() + "\" }").build();
+        }
+
+    }
+
+    /**
+     * Get MEP by MD name, MA name and Mep Id.
+     *
+     * @param mdName The name of a Maintenance Domain
+     * @param maName The name of a Maintenance Association belonging to the MD
+     * @param mepId The Id of the MEP
+     * @return 200 OK with details of the MEP or 500 on error
+     */
+    @GET
+    @Path("{mep_id}")
+    @Produces(MediaType.APPLICATION_JSON)
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response getMep(@PathParam("md_name") String mdName,
+            @PathParam("ma_name") String maName,
+            @PathParam("mep_id") short mepId) {
+        log.debug("GET called for MEP {}", mdName + "/" + maName + "/" + mepId);
+        try {
+            MdId mdId = MdIdCharStr.asMdId(mdName);
+            MaIdShort maId = MaIdCharStr.asMaId(maName);
+            MepEntry mepEntry = get(CfmMepService.class)
+                    .getMep(mdId, maId, MepId.valueOf(mepId));
+            if (mepEntry == null) {
+                return Response.serverError().entity("{ \"failure\":\"MEP " +
+                        mdName + "/" + maName + "/" + mepId + " not found\" }").build();
+            }
+            ObjectNode node = mapper().createObjectNode();
+            node.set("mep", codec(MepEntry.class).encode(mepEntry, this));
+            return ok(node).build();
+        } catch (CfmConfigException e) {
+            log.error("Get Mep {} failed because of exception",
+                    mdName + "/" + maName + "/" + mepId, e);
+            return Response.serverError().entity("{ \"failure\":\"" + e.toString() + "\" }").build();
+        }
+    }
+
+    /**
+     * Delete MEP by MD name, MA name and Mep Id.
+     *
+     * @param mdName The name of a Maintenance Domain
+     * @param maName The name of a Maintenance Association belonging to the MD
+     * @param mepIdShort The Id of the MEP
+     * @return 200 OK or 304 if not found, or 500 on error
+     */
+    @DELETE
+    @Path("{mep_id}")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response deleteMep(@PathParam("md_name") String mdName,
+            @PathParam("ma_name") String maName,
+            @PathParam("mep_id") short mepIdShort) {
+        log.debug("DELETE called for MEP " + mdName + "/" + maName + "/" + mepIdShort);
+        try {
+            MdId mdId = MdIdCharStr.asMdId(mdName);
+            MaIdShort maId = MaIdCharStr.asMaId(maName);
+            boolean deleted = get(CfmMepService.class)
+                    .deleteMep(mdId, maId, MepId.valueOf(mepIdShort));
+            if (!deleted) {
+                return Response.notModified(mdName + "/" + maName + "/" +
+                        mepIdShort + " did not exist").build();
+            } else {
+                return ok("{ \"success\":\"deleted " + mdName + "/" + maName +
+                        "/" + mepIdShort + "\" }").build();
+            }
+        } catch (CfmConfigException e) {
+            log.error("Delete Mep {} failed because of exception ",
+                    mdName + "/" + maName + "/" + mepIdShort, e);
+            return Response.serverError().entity("{ \"failure\":\"" +
+                    e.toString() + "\" }").build();
+        }
+    }
+
+    /**
+     * Create MEP with MD name, MA name and Mep Json.
+     *
+     * @onos.rsModel MepCreate
+     * @param mdName The name of a Maintenance Domain
+     * @param maName The name of a Maintenance Association belonging to the MD
+     * @param input A JSON formatted input stream specifying the Mep parameters
+     * @return 201 Created or 304 if already exists or 500 on error
+     */
+    @POST
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response createMep(@PathParam("md_name") String mdName,
+                              @PathParam("ma_name") String maName, InputStream input) {
+        log.debug("POST called to Create Mep");
+        try {
+            MdId mdId = MdIdCharStr.asMdId(mdName);
+            MaIdShort maId = MaIdCharStr.asMaId(maName);
+            MaintenanceAssociation ma = get(CfmMdService.class).getMaintenanceAssociation(mdId, maId).get();
+
+            ObjectMapper mapper = new ObjectMapper();
+            JsonNode cfg = mapper.readTree(input);
+            JsonCodec<Mep> mepCodec = codec(Mep.class);
+
+            Mep mep = ((MepCodec) mepCodec).decode((ObjectNode) cfg, this, mdName, maName);
+
+            Boolean issuccess = get(CfmMepService.class).createMep(mdId, maId, mep);
+            if (!issuccess) {
+                return Response.notModified(mdName + "/" + ma.maId() + "/" + mep.mepId() +
+                        " already exists").build();
+            }
+            return Response
+                    .created(new URI("md/" + mdName + "/ma/" + ma.maId() + "/mep/" + mep.mepId()))
+                    .entity("{ \"success\":\"mep " + mdName + "/" + ma.maId() + "/" + mep.mepId() + " created\" }")
+                    .build();
+        } catch (Exception | CfmConfigException e) {
+            log.error("Create Mep on " + mdName + "/" + maName + " failed because of exception {}",
+                      e.toString());
+            return Response.serverError()
+                    .entity("{ \"failure\":\"" + e.toString() + "\" }")
+                    .build();
+        }
+    }
+
+    /**
+     * Transmit Loopback on MEP with MD name, MA name and Mep Id.
+     *
+     * @onos.rsModel MepLbTransmit
+     * @param mdName The name of a Maintenance Domain
+     * @param maName The name of a Maintenance Association belonging to the MD
+     * @param mepIdShort The id of a MEP belonging to the MA
+     * @param input A JSON formatted input stream specifying the Mep parameters
+     * @return 202 Received with success message or 500 on error
+     */
+    @PUT
+    @Path("{mep_id}/transmit-loopback")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response transmitLoopback(
+            @PathParam("md_name") String mdName,
+            @PathParam("ma_name") String maName,
+            @PathParam("mep_id") short mepIdShort,
+            InputStream input) {
+        log.debug("PUT called to Transmit Loopback on Mep");
+
+        MdId mdId = MdIdCharStr.asMdId(mdName);
+        MaIdShort maId = MaIdCharStr.asMaId(maName);
+        MaintenanceDomain md = get(CfmMdService.class).getMaintenanceDomain(mdId).get();
+        MaintenanceAssociation ma = get(CfmMdService.class)
+                .getMaintenanceAssociation(mdId, maId).get();
+
+        MepId mepId = MepId.valueOf(mepIdShort);
+
+        try {
+            ObjectMapper mapper = new ObjectMapper();
+            JsonNode cfg = mapper.readTree(input);
+            JsonCodec<MepLbCreate> mepLbCreateCodec = codec(MepLbCreate.class);
+
+            MepLbCreate lbCreate = mepLbCreateCodec.decode((ObjectNode) cfg, this);
+            get(CfmMepService.class).transmitLoopback(md.mdId(), ma.maId(), mepId, lbCreate);
+        } catch (Exception | CfmConfigException e) {
+            log.error("Transmit Loopback on " + mdName + "/" + maName +
+                    "/{} failed", String.valueOf(mepIdShort), e);
+            return Response.serverError()
+                  .entity("{ \"failure\":\"" + e.toString() + "\" }")
+                  .build();
+        }
+
+        return Response.accepted()
+            .entity("{ \"success\":\"Loopback on MEP " + mdName + "/" + ma.maId() + "/"
+                    + mepId.id() + " started\" }").build();
+    }
+
+    /**
+     * Abort Loopback on MEP with MD name, MA name and Mep Id.
+     *
+     * @param mdName The name of a Maintenance Domain
+     * @param maName The name of a Maintenance Association belonging to the MD
+     * @param mepIdShort The id of a MEP belonging to the MA
+     * @return 202 Received with success message or 500 on error
+     */
+    @PUT
+    @Path("{mep_id}/abort-loopback")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response abortLoopback(
+            @PathParam("md_name") String mdName,
+            @PathParam("ma_name") String maName,
+            @PathParam("mep_id") short mepIdShort) {
+        log.debug("PUT called to Abort Loopback on Mep");
+
+        MdId mdId = MdIdCharStr.asMdId(mdName);
+        MaIdShort maId = MaIdCharStr.asMaId(maName);
+        MaintenanceDomain md = get(CfmMdService.class).getMaintenanceDomain(mdId).get();
+        MaintenanceAssociation ma = get(CfmMdService.class)
+                .getMaintenanceAssociation(mdId, maId).get();
+
+        MepId mepId = MepId.valueOf(mepIdShort);
+
+        try {
+            get(CfmMepService.class).abortLoopback(md.mdId(), ma.maId(), mepId);
+        } catch (CfmConfigException e) {
+            log.error("Abort Loopback on " + mdName + "/" + maName +
+                    "/{} failed", String.valueOf(mepIdShort), e);
+            return Response.serverError()
+                  .entity("{ \"failure\":\"" + e.toString() + "\" }")
+                  .build();
+        }
+
+        return Response.accepted()
+            .entity("{ \"success\":\"Loopback on MEP " + mdName + "/" + ma.maId() + "/"
+                    + mepId.id() + " aborted\" }").build();
+    }
+
+    /**
+     * Transmit Linktrace on MEP with MD name, MA name and Mep Id.
+     *
+     * @onos.rsModel MepLtTransmit
+     * @param mdName The name of a Maintenance Domain
+     * @param maName The name of a Maintenance Association belonging to the MD
+     * @param mepIdShort The id of a MEP belonging to the MA
+     * @param input A JSON formatted input stream specifying the Linktrace parameters
+     * @return 202 Received with success message or 500 on error
+     */
+    @PUT
+    @Path("{mep_id}/transmit-linktrace")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response transmitLinktrace(
+            @PathParam("md_name") String mdName,
+            @PathParam("ma_name") String maName,
+            @PathParam("mep_id") short mepIdShort,
+            InputStream input) {
+        log.debug("PUT called to Transmit Linktrace on Mep");
+
+        MdId mdId = MdIdCharStr.asMdId(mdName);
+        MaIdShort maId = MaIdCharStr.asMaId(maName);
+        MaintenanceDomain md = get(CfmMdService.class).getMaintenanceDomain(mdId).get();
+        MaintenanceAssociation ma = get(CfmMdService.class)
+                .getMaintenanceAssociation(mdId, maId).get();
+
+        MepId mepId = MepId.valueOf(mepIdShort);
+
+        try {
+            ObjectMapper mapper = new ObjectMapper();
+            JsonNode cfg = mapper.readTree(input);
+            JsonCodec<MepLtCreate> mepLtCreateCodec = codec(MepLtCreate.class);
+
+            MepLtCreate ltCreate = mepLtCreateCodec.decode((ObjectNode) cfg, this);
+            get(CfmMepService.class).transmitLinktrace(md.mdId(), ma.maId(), mepId, ltCreate);
+        } catch (Exception | CfmConfigException e) {
+            log.error("Transmit Linktrace on " + mdName + "/" + maName +
+                    "/{} failed", String.valueOf(mepIdShort), e);
+            return Response.serverError()
+                    .entity("{ \"failure\":\"" + e.toString() + "\" }")
+                    .build();
+        }
+
+        return Response.accepted()
+                .entity("{ \"success\":\"Linktrace on MEP " + mdName + "/" + ma.maId() + "/"
+                        + mepId.id() + " started\" }").build();
+    }
+}
