diff --git a/incubator/net/src/main/java/org/onosproject/incubator/net/l2monitoring/cfm/impl/CfmMepManager.java b/incubator/net/src/main/java/org/onosproject/incubator/net/l2monitoring/cfm/impl/CfmMepManager.java
new file mode 100644
index 0000000..5723466
--- /dev/null
+++ b/incubator/net/src/main/java/org/onosproject/incubator/net/l2monitoring/cfm/impl/CfmMepManager.java
@@ -0,0 +1,292 @@
+/*
+ * 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.incubator.net.l2monitoring.cfm.impl;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onosproject.core.CoreService;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.event.AbstractListenerManager;
+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.MaIdShort;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
+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.CfmMepEvent;
+import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMepListener;
+import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMepProgrammable;
+import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMepService;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.device.DeviceService;
+import org.slf4j.Logger;
+
+/**
+ * Provides implementation of the CFM North and South Bound Interfaces.
+ */
+@Component(immediate = true)
+@Service
+public class CfmMepManager
+    extends AbstractListenerManager<CfmMepEvent, CfmMepListener>
+    implements CfmMepService {
+
+    private final Logger log = getLogger(getClass());
+
+    private final DeviceListener deviceListener = new InternalDeviceListener();
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected MastershipService mastershipService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CfmMdService cfmMdService;
+
+    private static final int DEFAULT_POLL_FREQUENCY = 30;
+    private int fallbackMepPollFrequency = DEFAULT_POLL_FREQUENCY;
+
+    private IdGenerator idGenerator;
+
+    //FIXME Get rid of this hack - we will use this in memory to emulate
+    // a store for the short term.
+    //Note: This is not distributed and will not work in a clustered system
+    //TODO Create a MepStore for this
+    private Collection<Mep> mepCollection;
+
+
+    @Activate
+    public void activate() {
+        //FIXME Get rid of this local list
+        mepCollection = new ArrayList<>();
+
+        eventDispatcher.addSink(CfmMepEvent.class, listenerRegistry);
+        deviceService.addListener(deviceListener);
+        idGenerator = coreService.getIdGenerator("mep-ids");
+        log.info("CFM MEP Manager Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        deviceService.removeListener(deviceListener);
+        eventDispatcher.removeSink(CfmMepEvent.class);
+        log.info("CFM MEP Manager Stopped");
+        mepCollection.clear();
+    }
+
+    @Override
+    public Collection<MepEntry> getAllMeps(MdId mdName, MaIdShort maName)
+            throws CfmConfigException {
+        //Will throw IllegalArgumentException if ma does not exist
+        cfmMdService.getMaintenanceAssociation(mdName, maName);
+
+        Collection<MepEntry> mepEntryCollection = new ArrayList<>();
+
+        for (Mep mep:mepCollection) {
+            if (mep.mdId().equals(mdName) && mep.maId().equals(maName)) {
+                DeviceId mepDeviceId = mep.deviceId();
+                if (deviceService.getDevice(mepDeviceId) == null) {
+                    log.warn("Device not found/available " + mepDeviceId +
+                        " for MEP: " + mdName + "/" + maName + "/" + mep.mepId());
+                    continue;
+                } else if (!deviceService.getDevice(mepDeviceId)
+                                        .is(CfmMepProgrammable.class)) {
+                    throw new CfmConfigException("Device " + mepDeviceId +
+                            " does not support CfmMepProgrammable behaviour.");
+                }
+
+                log.debug("Retrieving MEP results for Mep {} in MD {}, MA {} "
+                    + "on Device {}", mep.mepId(), mdName, maName, mepDeviceId);
+                mepEntryCollection.add(deviceService
+                                        .getDevice(mepDeviceId)
+                                        .as(CfmMepProgrammable.class)
+                                        .getMep(mdName, maName, mep.mepId()));
+            }
+        }
+
+        return mepEntryCollection;
+    }
+
+    @Override
+    public MepEntry getMep(MdId mdName, MaIdShort maName, MepId mepId) throws CfmConfigException {
+        //Will throw IllegalArgumentException if ma does not exist
+        cfmMdService.getMaintenanceAssociation(mdName, maName);
+
+        for (Mep mep : mepCollection) {
+            if (mep.mdId().equals(mdName) && mep.maId().equals(maName)
+                    && mep.mepId().equals(mepId)) {
+
+                DeviceId mepDeviceId = mep.deviceId();
+                if (deviceService.getDevice(mepDeviceId) == null) {
+                    throw new CfmConfigException("Device not found " + mepDeviceId);
+                } else if (!deviceService.getDevice(mepDeviceId).is(CfmMepProgrammable.class)) {
+                    throw new CfmConfigException("Device " + mepDeviceId +
+                            " does not support CfmMepProgrammable behaviour.");
+                }
+
+                log.debug("Retrieving MEP reults for Mep {} in MD {}, MA {} on Device {}",
+                        mep.mepId(), mdName, maName, mepDeviceId);
+
+                return deviceService.getDevice(mepDeviceId)
+                        .as(CfmMepProgrammable.class).getMep(mdName, maName, mepId);
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public boolean deleteMep(MdId mdName, MaIdShort maName, MepId mepId) throws CfmConfigException {
+        //Will throw IllegalArgumentException if ma does not exist
+        cfmMdService.getMaintenanceAssociation(mdName, maName);
+
+        for (Mep mep : mepCollection) {
+            if (mep.mdId().equals(mdName) && mep.maId().equals(maName)
+                    && mep.mepId().equals(mepId)) {
+                Device mepDevice = deviceService.getDevice(mep.deviceId());
+                if (mepDevice == null || !mepDevice.is(CfmMepProgrammable.class)) {
+                    throw new CfmConfigException("Unexpeced fault on device drier for "
+                            + mep.deviceId());
+                }
+                boolean deleted = false;
+                try {
+                     deleted = mepDevice.as(CfmMepProgrammable.class)
+                            .deleteMep(mdName, maName, mepId);
+                } catch (CfmConfigException e) {
+                    log.warn("MEP could not be deleted on device - perhaps it "
+                            + "does not exist. Continuing");
+                    mepCollection.remove(mep);
+                    return false;
+                }
+                if (deleted) {
+                    mepCollection.remove(mep);
+                    return true;
+                } else {
+                    return false;
+                }
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public boolean createMep(MdId mdName, MaIdShort maName, Mep newMep) throws CfmConfigException {
+        log.debug("Creating MEP " + newMep.mepId() + " on MD {}, MA {} on Device {}",
+                mdName, maName, newMep.deviceId().toString());
+        for (Mep mep : mepCollection) {
+            if (mep.mdId().equals(mdName) && mep.maId().equals(maName)
+                    && mep.mepId().equals(newMep.mepId())) {
+                return false;
+            }
+        }
+
+        //Will throw IllegalArgumentException if ma does not exist
+        cfmMdService.getMaintenanceAssociation(mdName, maName);
+
+        DeviceId mepDeviceId = newMep.deviceId();
+        if (deviceService.getDevice(mepDeviceId) == null) {
+            throw new CfmConfigException("Device not found " + mepDeviceId);
+        } else if (!deviceService.getDevice(mepDeviceId).is(CfmMepProgrammable.class)) {
+            throw new CfmConfigException("Device " + mepDeviceId + " does not support CfmMepProgrammable behaviour.");
+        }
+
+        boolean deviceResult =
+                deviceService.getDevice(mepDeviceId).as(CfmMepProgrammable.class).createMep(mdName, maName, newMep);
+        log.debug("MEP created on {}", mepDeviceId);
+        if (deviceResult) {
+            return mepCollection.add(newMep);
+        } else {
+            return deviceResult;
+        }
+    }
+
+    @Override
+    public void transmitLoopback(MdId mdName, MaIdShort maName,
+            MepId mepId, MepLbCreate lbCreate) throws CfmConfigException {
+        for (Mep mep : mepCollection) {
+            if (mep.mdId().equals(mdName) && mep.maId().equals(maName)
+                    && mep.mepId().equals(mepId)) {
+                log.debug("Transmitting Loopback on MEP {}/{}/{} on Device {}",
+                        mdName, maName, mepId, mep.deviceId());
+                deviceService.getDevice(mep.deviceId())
+                    .as(CfmMepProgrammable.class)
+                    .transmitLoopback(mdName, maName, mepId, lbCreate);
+                return;
+            }
+        }
+        throw new CfmConfigException("Mep " + mdName + "/" + maName + "/"
+                + mepId + " not found when calling Transmit Loopback");
+    }
+
+    @Override
+    public void abortLoopback(MdId mdName, MaIdShort maName, MepId mepId)
+            throws CfmConfigException {
+        for (Mep mep : mepCollection) {
+            if (mep.mdId().equals(mdName) && mep.maId().equals(maName)
+                    && mep.mepId().equals(mepId)) {
+                log.debug("Aborting Loopback on MEP {}/{}/{} on Device {}",
+                        mdName, maName, mepId, mep.deviceId());
+                deviceService.getDevice(mep.deviceId())
+                    .as(CfmMepProgrammable.class)
+                    .abortLoopback(mdName, maName, mepId);
+                return;
+            }
+        }
+        throw new CfmConfigException("Mep " + mdName + "/" + maName + "/"
+                + mepId + " not found when calling Transmit Loopback");
+    }
+
+    @Override
+    public void transmitLinktrace(MdId mdName, MaIdShort maName, MepId mepId,
+            MepLtCreate ltCreate) {
+        throw new UnsupportedOperationException("Not yet implemented");
+    }
+
+    private class InternalDeviceListener implements DeviceListener {
+        @Override
+        public void event(DeviceEvent event) {
+            switch (event.type()) {
+                case DEVICE_REMOVED:
+                case DEVICE_AVAILABILITY_CHANGED:
+                    DeviceId deviceId = event.subject().id();
+                    if (!deviceService.isAvailable(deviceId)) {
+                        log.warn("Device {} has been removed or changed", deviceId);
+                    }
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+}
