diff --git a/ecord/carrierethernet/pom.xml b/ecord/carrierethernet/pom.xml
new file mode 100644
index 0000000..516f264
--- /dev/null
+++ b/ecord/carrierethernet/pom.xml
@@ -0,0 +1,179 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>org.onosproject</groupId>
+    <artifactId>onos-app-carrierethernet</artifactId>
+    <version>1.6.0-SNAPSHOT</version>
+    <packaging>bundle</packaging>
+
+    <description>Application for installing MEF services in ONOS</description>
+    <url>http://onosproject.org</url>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <onos.version>1.6.0-SNAPSHOT</onos.version>
+        <onos.app.name>org.onosproject.ecord.carrierethernet</onos.app.name>
+        <!-- TODO App dependency not working? -->
+        <onos.app.requires>org.onosproject.incubator.rpc,org.onosproject.incubator.rpc.grpc</onos.app.requires>
+        <onos.app.origin>Open Networking Lab</onos.app.origin>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-api</artifactId>
+            <version>${onos.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-cli</artifactId>
+            <version>${onos.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-drivers</artifactId>
+            <version>${onos.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-app-ecord-metro</artifactId>
+            <version>${onos.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.karaf.shell</groupId>
+            <artifactId>org.apache.karaf.shell.console</artifactId>
+            <version>3.0.3</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onlab-osgi</artifactId>
+            <version>${onos.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.12</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-api</artifactId>
+            <version>${onos.version}</version>
+            <scope>test</scope>
+            <classifier>tests</classifier>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.scr.annotations</artifactId>
+            <version>1.9.12</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+            <version>4.3.1</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>openflowj</artifactId>
+            <version>0.9.3.onos-SNAPSHOT</version>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <groupId>org.apache.karaf.tooling</groupId>
+                    <artifactId>karaf-maven-plugin</artifactId>
+                    <version>3.0.5</version>
+                    <extensions>true</extensions>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <version>2.5.3</version>
+                <extensions>true</extensions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>2.5.1</version>
+                <configuration>
+                    <source>1.8</source>
+                    <target>1.8</target>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-scr-plugin</artifactId>
+                <version>1.20.0</version>
+                <executions>
+                    <execution>
+                        <id>generate-scr-srcdescriptor</id>
+                        <goals>
+                            <goal>scr</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <supportedProjectTypes>
+                        <supportedProjectType>bundle</supportedProjectType>
+                        <supportedProjectType>war</supportedProjectType>
+                    </supportedProjectTypes>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.onosproject</groupId>
+                <artifactId>onos-maven-plugin</artifactId>
+                <version>1.5</version>
+                <executions>
+                    <execution>
+                        <id>cfg</id>
+                        <phase>generate-resources</phase>
+                        <goals>
+                            <goal>cfg</goal>
+                        </goals>
+                    </execution>
+                    <execution>
+                        <id>swagger</id>
+                        <phase>generate-sources</phase>
+                        <goals>
+                            <goal>swagger</goal>
+                        </goals>
+                    </execution>
+                    <execution>
+                        <id>app</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>app</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetBandwidthProfile.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetBandwidthProfile.java
new file mode 100644
index 0000000..9dfe5f4
--- /dev/null
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetBandwidthProfile.java
@@ -0,0 +1,151 @@
+/*
+ * 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.ecord.carrierethernet.app;
+
+import org.onlab.util.Bandwidth;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Bandwidth profile for a CE UNI.
+ */
+public class CarrierEthernetBandwidthProfile {
+
+    public enum Type {
+        INTERFACE, EVC, COS
+    }
+
+    protected String id;
+    protected String cfgId;
+    protected Type type;
+    protected Bandwidth cir;
+    protected Bandwidth eir;
+    protected long cbs;
+    protected long ebs;
+
+    public CarrierEthernetBandwidthProfile(String id, String cfgId, Type type,
+                                           Bandwidth cir, Bandwidth eir, long cbs, long ebs) {
+        this.id = id;
+        this.cfgId = cfgId;
+        this.type = type;
+        this.cir = cir;
+        this.eir = eir;
+        this.cbs = cbs;
+        this.ebs = ebs;
+    }
+
+    /**
+     * Returns BWP string identifier.
+     *
+     * @return BWP string identifier
+     */
+    public String id() {
+        return id;
+    }
+
+    /**
+     * Returns BWP string config identifier.
+     *
+     * @return BWP string config identifier
+     */
+    public String cfgId() {
+        return cfgId;
+    }
+
+    /**
+     * Returns BWP type (INTERFACE, EVC, COS).
+     *
+     * @return BWP type
+     */
+    public Type type() {
+        return type;
+    }
+
+    /**
+     * Returns BWP CIR rate.
+     *
+     * @return BWP CIR rate
+     */
+    public Bandwidth cir() {
+        return cir;
+    }
+
+    /**
+     * Returns BWP EIR rate.
+     *
+     * @return BWP EIR rate
+     */
+    public Bandwidth eir() {
+        return eir;
+    }
+
+    /**
+     * Returns BWP CBS in Bytes.
+     *
+     * @return BWP CBS in Bytes
+     */
+    public long cbs() {
+        return cbs;
+    }
+
+    /**
+     * Returns BWP EBS in Bytes.
+     *
+     * @return BWP EBS in Bytes
+     */
+    public long ebs() {
+        return ebs;
+    }
+
+    /**
+     * Sets BWP id.
+     *
+     * @param id the id to set
+     */
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    /**
+     * Sets BWP CIR rate.
+     *
+     * @param cir the CIR to set
+     */
+    public void setCir(Bandwidth cir) {
+        this.cir = cir;
+    }
+
+    /**
+     * Sets BWP EIR rate.
+     *
+     * @param eir the EIR to set
+     */
+    public void setEir(Bandwidth eir) {
+        this.eir = eir;
+    }
+
+    public String toString() {
+
+        return toStringHelper(this)
+                .add("id", id)
+                .add("type", type)
+                .add("cir", cir)
+                .add("cbs", cbs)
+                .add("eir", eir)
+                .add("ebs", ebs).toString();
+    }
+
+}
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetManager.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetManager.java
new file mode 100644
index 0000000..7e0b36c
--- /dev/null
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetManager.java
@@ -0,0 +1,563 @@
+/*
+ * 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.ecord.carrierethernet.app;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.packet.VlanId;
+
+import org.onlab.util.Bandwidth;
+import org.onosproject.ecord.metro.api.MetroConnectivityId;
+import org.onosproject.ecord.metro.api.MetroPathEvent;
+import org.onosproject.ecord.metro.api.MetroPathListener;
+import org.onosproject.ecord.metro.api.MetroPathService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Device;
+import org.onosproject.net.Port;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.link.LinkService;
+import org.slf4j.Logger;
+
+import java.time.Duration;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+@Component(immediate = true)
+@Service(value = CarrierEthernetManager.class)
+public class CarrierEthernetManager {
+
+    private final Logger log = getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected LinkService linkService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected MetroPathService metroPathService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CarrierEthernetPacketProvisioner cePktProvisioner;
+
+    private MetroPathListener metroEventListener = new MetroEventListener();
+
+    // Keeps track of the next S-VLAN tag the app will try to use
+    private static short curVlanId = 0;
+
+    private static final int METRO_CONNECT_TIMEOUT_MILLIS = 7000;
+
+    private static final boolean PACKET_OPTICAL_TOPO = true;
+
+    // TODO: Implement distributed store for CE services
+    // The installed CE services
+    private final Map<String, CarrierEthernetService> serviceMap = new ConcurrentHashMap<>();
+
+    // TODO: Refactor this part
+    private final Map<MetroConnectivityId, MetroPathEvent.Type> metroConnectStatusMap = new ConcurrentHashMap<>();
+
+    // TODO: Implement distributed store for CE UNIs
+    // The installed CE UNIs
+    private final Map<String, CarrierEthernetUni> uniMap = new ConcurrentHashMap<>();
+
+    /**
+     * Activate this component.
+     */
+    @Activate
+    public void activate() {
+        metroPathService.addListener(metroEventListener);
+    }
+
+    /**
+     * Deactivate this component.
+     */
+    @Deactivate
+    public void deactivate() {
+        removeAllServices();
+        metroPathService.removeListener(metroEventListener);
+    }
+
+    /**
+     * Returns the map of installed services.
+     *
+     * @return map of installed services
+     */
+    public  Map<String, CarrierEthernetService> serviceMap() {
+        return this.serviceMap;
+    }
+
+    // TODO: Add method to remove a UNI from an already installed service
+
+    /**
+     * Get an installed CE using its id.
+     *
+     * @return the CE service definition or null if the service doesn't exist
+     */
+    public CarrierEthernetService getService(String serviceId) {
+        return ((serviceMap.get(serviceId) == null) ? null : serviceMap.get(serviceId));
+    }
+
+    /**
+     * Get the map containing all installed services
+     *
+     * @return the CE service map
+     */
+    public Map<String, CarrierEthernetService> getServiceMap() {
+        return serviceMap;
+    }
+
+    /**
+     * Get the map containing all global UNIs
+     *
+     * @return the global UNI map
+     */
+    public Map<String, CarrierEthernetUni> getUniMap() {
+        return uniMap;
+    }
+
+    /**
+     * Verify the validity of a CE service definition taking also into account current network status.
+     *
+     * @param originalService the provided CE service definition
+     * @return a valid, potentially modified service description, or null if the service could not be validated
+     */
+    private CarrierEthernetService validateService(CarrierEthernetService originalService) {
+
+        // Make a copy of the provided service, since it may be modified
+        CarrierEthernetService service = originalService;
+
+        // Try to set a unique VLAN id for the service unless the service is being updated
+        // TODO: Add different connectivity types
+        if (service.vlanId() == null) {
+            service.setVlanId(generateVlanId());
+            if (service.vlanId() == null) {
+                log.error("No available VLAN id found.");
+                return null;
+            }
+        }
+
+        // Verify that CE-VLAN ID is provided to either all UNIs or none and set the virtualService flag accordingly
+        boolean isVirtual = false;
+        Iterator<CarrierEthernetUni> it = service.uniSet().iterator();
+        while (it.hasNext()) {
+            CarrierEthernetUni uni = it.next();
+            if (uni.ceVlanId() == null && isVirtual) {
+                log.error("Could not validate the virtual status of the service.");
+                return null;
+            } else if (uni.ceVlanId() != null){
+                isVirtual = true;
+            }
+        }
+        service.setIsVirtual(isVirtual);
+
+        // Set unique id for the service unless the service is being updated
+        if (service.id() == null) {
+            service.setId(generateServiceId(service));
+        }
+
+        Set<CarrierEthernetUni> validatedUniSet = new HashSet<>();
+
+        // Check the UNIs of the service, possibly removing UNIs that are incompatible with existing ones
+        it = service.uniSet().iterator();
+        while (it.hasNext()) {
+            CarrierEthernetUni uni = it.next();
+            // Change the name of the UNI's BWP to the service name if it is an EVC BWP
+            if (uni.bwp().type().equals(CarrierEthernetBandwidthProfile.Type.EVC)) {
+                uni.bwp().setId(service.id());
+            }
+            // Check first if UNI already exists by checking against the global UNI Map
+            if (uniMap.keySet().contains(uni.id())) {
+                CarrierEthernetUni existingUni = uniMap.get(uni.id());
+                // Check if the service-specific UNI is compatible with the global one
+                if (!(existingUni.validateServiceUni(uni))) {
+                    // If service is of ROOT_MULTIPOINT type and we have removed the root, return null
+                    if (service.type() == CarrierEthernetService.Type.ROOT_MULTIPOINT &&
+                            uni.type() == CarrierEthernetUni.Type.ROOT) {
+                        log.error("Root UNI could not be added to %s service.", service.type().name());
+                        return null;
+                    }
+                    log.warn("UNI {} could not be added to service.", uni.id());
+                    continue;
+                } else {
+                    // Add UNI to service description
+                    validatedUniSet.add(uni);
+                }
+            } else {
+                // Add UNI to service description
+                validatedUniSet.add(uni);
+            }
+        }
+
+        // Update the service UNI set, based on the validated UNIs
+        service.setUniSet(validatedUniSet);
+
+        if (service.type().equals(CarrierEthernetService.Type.ROOT_MULTIPOINT) && (service.uniSet().size() < 2)) {
+            log.error("{} service requires at least two UNIs.", service.type().name());
+            return null;
+        }
+
+        if (service.type().equals(CarrierEthernetService.Type.MULTIPOINT_TO_MULTIPOINT) &&
+                (service.uniSet().size() < 3)) {
+            log.error("{} service requires more than two UNIs.", service.type().name());
+            return null;
+        }
+
+        if (service.type().equals(CarrierEthernetService.Type.POINT_TO_POINT) && (service.uniSet().size() != 2)) {
+            log.error("{} service requires exactly two UNIs.", service.type().name());
+            return null;
+        }
+
+        return service;
+    }
+
+    /**
+     * Establish connectivity according to the service type (E-Line, E-Tree, E-LAN) and the service parameters.
+     *
+     * @param originalService the CE service definition
+     * @return boolean value indicating whether the service could be established even partially
+     */
+    public boolean establishConnectivity(CarrierEthernetService originalService) {
+
+        // If service already exists, remove it and reestablish with new parameters
+        if (originalService.id() != null && serviceMap.containsKey(originalService.id())) {
+            return updateService(originalService);
+        } else {
+            originalService.setId(null);
+        }
+
+        CarrierEthernetService service = validateService(originalService);
+
+        boolean outcome = false;
+
+        if (service == null) {
+            log.error("Service could not be installed, please check log for details.");
+            return outcome;
+        }
+
+        // Temporary set for iterating through service UNI pairs
+        Set<CarrierEthernetUni> uniSet = service.uniSet();
+
+        // Temporary set for indicating which UNIs were finally included in the service
+        Set<CarrierEthernetUni> usedUniSet = new HashSet<>();
+
+        Iterator<CarrierEthernetUni> it1 = uniSet.iterator();
+        while (it1.hasNext()) {
+
+            CarrierEthernetUni uni1 = it1.next();
+
+            // Iterate through all the remaining UNIs
+            Iterator<CarrierEthernetUni> it2 = uniSet.iterator();
+            while (it2.hasNext()) {
+
+                CarrierEthernetUni uni2 = it2.next();
+
+                // Skip equals
+                if (uni1.equals(uni2)) {
+                    continue;
+                }
+
+                // Do not establish connectivity between leaf UNIs (applies to Rooted_Multipoint)
+                if (uni1.type() == CarrierEthernetUni.Type.LEAF && uni2.type() == CarrierEthernetUni.Type.LEAF) {
+                    continue;
+                }
+
+                MetroConnectivityId metroConnectId = null;
+
+                if (PACKET_OPTICAL_TOPO) {
+                    metroConnectId = setupMetroConnectivity(uni1.cp(), uni2.cp(), uni1.bwp().cir(), service.latency());
+
+                    if (metroConnectId == null ||
+                            metroConnectStatusMap.get(metroConnectId) != MetroPathEvent.Type.PATH_INSTALLED) {
+                        log.error("Could not establish metro connectivity between {} and {}" +
+                                        " (metro id and status: {}, {})", uni1.cp(), uni2.cp(), metroConnectId,
+                                (metroConnectId == null ? "null" : metroConnectStatusMap.get(metroConnectId)));
+                        //continue;
+                    }
+
+                    if (metroConnectId != null) {
+                        service.setMetroConnectivityId(metroConnectId);
+                        service.setMetroConnectivityStatus(metroConnectStatusMap.get(metroConnectId));
+                    }
+
+                    log.info("Metro connectivity id and status for CE service {}: {}, {}", service.id(),
+                            service.metroConnectivity().id(), service.metroConnectivity().status());
+
+                    // FIXME: Temporary hack for ONS: Get vlanId from metro app
+                    if (metroConnectId != null) {
+                        Optional<VlanId> vlanId = metroPathService.getVlanId(metroConnectId);
+                        if (vlanId.isPresent()) {
+                            service.setVlanId(vlanId.get());
+                        }
+                    }
+                }
+
+                if (!cePktProvisioner.setupConnectivity(uni1, uni2, service)) {
+                    log.warn("Could not set up packet connectivity between {} and {}", uni1, uni2);
+                    removeMetroConnectivity(metroConnectId);
+                    continue;
+                }
+
+                // Indicate that connection for at least one UNI pair has been established
+                outcome = true;
+
+                // Add UNIs to the set of UNIs used by the service
+                usedUniSet.add(uni1);
+                usedUniSet.add(uni2);
+            }
+            // Remove UNI from temporary set so that each pair is visited only once
+            it1.remove();
+        }
+
+        // Update the service UNI set, based on the UNIs actually used
+        service.setUniSet(usedUniSet);
+
+        // If no pair was connected, do not register the service
+        if (outcome) {
+            serviceMap.put(service.id(), service);
+            cePktProvisioner.applyBandwidthProfiles(service);
+            // Apply the BWPs of the service UNI to the global UNIs, creating them if needed
+            applyBandwidthProfiles(service.uniSet());
+        }
+
+        return outcome;
+    }
+
+    /**
+     * Reestablish connectivity for an existing service.
+     *
+     * @param originalService the updated CE service definition
+     * @return boolean value indicating whether the service could be established even partially
+     */
+    public boolean updateService(CarrierEthernetService originalService) {
+        // Just checking again
+        if (serviceMap.containsKey(originalService.id())) {
+            log.info("Updating existing service {}", originalService.id());
+            // Keep the VLAN ID of the original service
+            originalService.setVlanId(serviceMap.get(originalService.id()).vlanId());
+            removeService(originalService.id());
+        }
+        return establishConnectivity(originalService);
+    }
+
+    /**
+     * Applies bandwidth profiles to the UNIs of a service and adds them if needed to the global UNI map.
+     *
+     * @param  uniSet set of UNIs that are included in the service
+     */
+    private void applyBandwidthProfiles(Set<CarrierEthernetUni> uniSet) {
+
+        uniSet.forEach(uni -> {
+            if (!(uniMap.keySet().contains(uni.id()))) {
+                // Just add the UNI as it appears at the service
+                uniMap.put(uni.id(), uni);
+            } else {
+                // Add UNI resources (BWP, CE-VLAN ID) to existing global UNI
+                CarrierEthernetUni newUni = uniMap.get(uni.id());
+                newUni.addServiceUni(uni);
+                // Update config identifier
+                newUni.setCfgId(uni.cfgId());
+                uniMap.put(uni.id(), newUni);
+            }
+        });
+    }
+
+    /**
+     * Removes bandwidth profiles from the UNIs of a service and removes them if needed from the global UNI map.
+     *
+     * @param serviceId the CE service id
+     */
+    private void removeBandwidthProfiles(String serviceId) {
+
+        serviceMap.get(serviceId).uniSet().forEach(uni -> {
+            // TODO: Check if the bandwidth profile really needs to be removed (e.g. may be CoS)
+            cePktProvisioner.removeBandwidthProfiles(serviceMap.get(serviceId));
+
+            // Remove UNI resources (BWP, CE-VLAN ID) from global UNI
+            CarrierEthernetUni newUni = uniMap.get(uni.id());
+            newUni.removeServiceUni(uni);
+            uniMap.put(uni.id(), newUni);
+        });
+    }
+
+    /**
+     * Removes all resources associated with the application.
+     *
+     * This will be called either from the deactivate method or as a response to a CLI command.
+     * */
+    public void removeAllServices() {
+        serviceMap.keySet().forEach(serviceId -> {
+            CarrierEthernetService service = serviceMap.get(serviceId);
+            cePktProvisioner.removeConnectivity(service);
+            cePktProvisioner.removeBandwidthProfiles(service);
+            removeMetroConnectivity(service.metroConnectivity().id());
+            removeBandwidthProfiles(serviceId);
+        });
+        serviceMap.clear();
+    }
+
+    /**
+     * Removes all resources associated with a specific CE service.
+     *
+     * @param serviceId the CE service id
+     * */
+    public void removeService(String serviceId) {
+        if (serviceMap.containsKey(serviceId)) {
+            CarrierEthernetService service = serviceMap.get(serviceId);
+            cePktProvisioner.removeConnectivity(service);
+            cePktProvisioner.removeBandwidthProfiles(service);
+            removeMetroConnectivity(service.metroConnectivity().id());
+            removeBandwidthProfiles(serviceId);
+            serviceMap.remove(serviceId);
+        }
+    }
+
+    /**
+     * Generates a unique vlanId in the context of the CE app.
+     *
+     * @return the generated vlanId or null if none found
+     * */
+    public VlanId generateVlanId() {
+
+        Set<VlanId> vlanIdSet = new HashSet<>();
+        VlanId vlanId = null;
+
+        serviceMap.values().forEach(service -> vlanIdSet.add(service.vlanId));
+
+        // If all vlanIds are being used return null, else try to find the next available one
+        if (vlanIdSet.size() <  VlanId.MAX_VLAN - 1) {
+            do {
+                curVlanId = nextValidShort(curVlanId);
+                vlanId = VlanId.vlanId(curVlanId);
+            }
+            while (vlanIdSet.contains(vlanId));
+        }
+
+        return vlanId;
+    }
+
+    private short nextValidShort(short i) {
+
+        if (i >= VlanId.MAX_VLAN || i <= 0) {
+            return 1;
+        } else {
+            return (short) (i + 1);
+        }
+    }
+
+    /**
+     * Generates a unique id in the context of the CE app.
+     *
+     * @return the generated vlanId or null if none found
+     * */
+    public String generateServiceId(CarrierEthernetService service) {
+
+        // TODO: Add different connectivity types
+
+        String tmpType;
+
+        if (service.type().equals(CarrierEthernetService.Type.POINT_TO_POINT)) {
+            tmpType = "Line";
+        } else if (service.type().equals(CarrierEthernetService.Type.MULTIPOINT_TO_MULTIPOINT)) {
+            tmpType = "LAN";
+        } else {
+            tmpType = "Tree";
+        }
+
+        String serviceId = "E" + (service.isVirtual() ? "V" : "") + "P-" + tmpType + "-" +
+                service.vlanId().toString();
+
+        return serviceId;
+    }
+
+    /**
+     * Adds all potential UNIs to the global UNI map if they are not already there.
+     *
+     * */
+    // TODO: Modify to return set of UNIs so that method can be reused in Uni Completer
+    public void addGlobalUnis() {
+
+        CarrierEthernetUni uni;
+        // Generate the device ID/port number identifiers
+        for (Device device : deviceService.getDevices()) {
+            for (Port port : deviceService.getPorts(device.id())) {
+                // Consider only physical ports which are currently active
+                if (!port.number().isLogical() && port.isEnabled()) {
+                    String cpString = device.id().toString() + "/" + port.number();
+                    ConnectPoint cp = ConnectPoint.deviceConnectPoint(cpString);
+                    // Add the UNI associated with generated connect point only if it doesn't belong to any link
+                    // and only if it belongs to a packet switch
+                    if (linkService.getEgressLinks(cp).isEmpty() && linkService.getIngressLinks(cp).isEmpty() &&
+                            device.type().equals(Device.Type.SWITCH)) {
+                        uni = new CarrierEthernetUni(cp, cpString, null, null, null);
+                        // Add UNI only if it's not already there
+                        if (!uniMap.containsKey(uni.id())) {
+                            uniMap.put(uni.id(), uni);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private class MetroEventListener implements MetroPathListener {
+
+        @Override
+        public void event(MetroPathEvent event) {
+            switch (event.type()) {
+                case PATH_INSTALLED: case PATH_REMOVED:
+                    log.info("Metro path event {} received for {}.", event.type(), event.subject());
+                    metroConnectStatusMap.put(event.subject(), event.type());
+                    break;
+                default:
+                    log.error("Unexpected metro event type.");
+                    break;
+            }
+        }
+    }
+
+    private MetroConnectivityId setupMetroConnectivity(ConnectPoint ingress, ConnectPoint egress,
+                                                       Bandwidth bandwidth, Duration latency) {
+        MetroConnectivityId metroConnectId = metroPathService.setupConnectivity(ingress, egress, bandwidth, latency);
+        if (metroConnectId != null) {
+            long startTime = System.currentTimeMillis();
+            while (((System.currentTimeMillis() - startTime) < METRO_CONNECT_TIMEOUT_MILLIS) &&
+                    (metroConnectStatusMap.get(metroConnectId) != MetroPathEvent.Type.PATH_INSTALLED)) {
+            }
+        }
+        return metroConnectId;
+    }
+
+    private void removeMetroConnectivity(MetroConnectivityId metroConnectId) {
+        if (metroConnectId != null) {
+            metroPathService.removeConnectivity(metroConnectId);
+            long startTime = System.currentTimeMillis();
+            while (((System.currentTimeMillis() - startTime) < METRO_CONNECT_TIMEOUT_MILLIS) &&
+                    (metroConnectStatusMap.get(metroConnectId) != MetroPathEvent.Type.PATH_REMOVED)) {
+            }
+        }
+    }
+
+}
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetOpenFlowPacketNodeManager.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetOpenFlowPacketNodeManager.java
new file mode 100644
index 0000000..92dd5f9
--- /dev/null
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetOpenFlowPacketNodeManager.java
@@ -0,0 +1,844 @@
+package org.onosproject.ecord.carrierethernet.app;
+
+import com.google.common.collect.Lists;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.VlanId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.core.DefaultGroupId;
+import org.onosproject.core.GroupId;
+import org.onosproject.driver.extensions.OfdpaMatchVlanVid;
+import org.onosproject.driver.extensions.OfdpaSetVlanVid;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.DefaultFlowRule;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criteria;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.PortCriterion;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flow.instructions.Instructions;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.DefaultForwardingObjective;
+import org.onosproject.net.flowobjective.FilteringObjective;
+import org.onosproject.net.flowobjective.DefaultFilteringObjective;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.group.Group;
+import org.onosproject.net.group.GroupBucket;
+import org.onosproject.net.group.GroupBuckets;
+import org.onosproject.net.group.GroupKey;
+import org.onosproject.net.group.DefaultGroupKey;
+import org.onosproject.net.group.DefaultGroupBucket;
+import org.onosproject.net.group.DefaultGroupDescription;
+import org.onosproject.net.group.GroupDescription;
+import org.onosproject.net.group.GroupService;
+import org.onosproject.net.meter.Meter;
+import org.onosproject.net.meter.MeterId;
+import org.onosproject.net.meter.MeterRequest;
+import org.onosproject.net.meter.Band;
+import org.onosproject.net.meter.DefaultBand;
+import org.onosproject.net.meter.MeterService;
+import org.onosproject.net.meter.DefaultMeterRequest;
+import org.onosproject.openflow.controller.Dpid;
+import org.onosproject.openflow.controller.OpenFlowController;
+import org.onosproject.openflow.controller.OpenFlowSwitch;
+import org.projectfloodlight.openflow.protocol.OFVersion;
+import org.slf4j.Logger;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Collection;
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ *  Class used to control Carrier Ethernet nodes according to the OpenFlow protocol.
+ */
+@Component(immediate = true)
+@Service (value = CarrierEthernetOpenFlowPacketNodeManager.class)
+public class CarrierEthernetOpenFlowPacketNodeManager extends CarrierEthernetPacketNodeManager {
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected FlowRuleService flowRuleService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected GroupService groupService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected MeterService meterService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected FlowObjectiveService flowObjectiveService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected OpenFlowController controller;
+
+    private final Logger log = getLogger(getClass());
+
+    private static ApplicationId appId;
+
+    private static final int PRIORITY = 50000;
+
+    // TODO: Get the OFDPA2.0 table numbers from the OFDPA Pipeline Class?
+    protected static final int PORT_TABLE = 0;
+    protected static final int VLAN_TABLE = 10;
+    protected static final int TMAC_TABLE = 20;
+    protected static final int UNICAST_ROUTING_TABLE = 30;
+    protected static final int MULTICAST_ROUTING_TABLE = 40;
+    protected static final int MPLS_TABLE_0 = 23;
+    protected static final int MPLS_TABLE_1 = 24;
+    protected static final int BRIDGING_TABLE = 50;
+    protected static final int ACL_TABLE = 60;
+    protected static final int MAC_LEARNING_TABLE = 254;
+
+    // TODO: Below maps to be replaced by the meter ids, egress cps and flow rules kept with each service (?)
+    private final Map<String, Set<DeviceMeterId>> deviceMeterIdMap = new HashMap<>();
+    private final Map<String, Set<ConnectPoint>> egressCpMap = new HashMap<>();
+    private final Map<String, Set<FlowRule>> flowRuleMap = new HashMap();
+
+    @Activate
+    protected void activate() {
+        appId = coreService.registerApplication("org.onosproject.ecord.carrierethernet");
+    }
+
+    @Deactivate
+    protected void deactivate() {}
+
+    @Override
+    public void setNodeForwarding(CarrierEthernetService service, CarrierEthernetUni srcUni, CarrierEthernetUni dstUni,
+                           ConnectPoint ingress, ConnectPoint egress, boolean first, boolean last) {
+
+        // TODO: Produce error if ingress and egress do not belong to same device
+
+        Set<ConnectPoint> egressCpSet = egressCpMap.get(service.id());
+        if (egressCpSet == null) {
+            egressCpSet = new HashSet<>();
+        }
+        Set<FlowRule> flowRuleSet = flowRuleMap.get(service.id());
+        if (flowRuleSet == null) {
+            flowRuleSet = new HashSet<>();
+        }
+
+        flowRuleSet.addAll(createFlowRules(service.id(), srcUni.ceVlanId(), service.vlanId(),
+                ingress, egress, first, last));
+
+        egressCpSet.add(egress);
+
+        egressCpMap.put(service.id(), egressCpSet);
+        flowRuleMap.put(service.id(), flowRuleSet);
+
+    }
+
+    // FIXME: Temporary solution for establishing flow rules according to switch type
+    private Set<FlowRule> createFlowRules(String serviceId, VlanId ceVlanId, VlanId vlanId,
+                                          ConnectPoint ingress, ConnectPoint egress, boolean first, boolean last) {
+
+        Dpid dpid = Dpid.dpid(egress.deviceId().uri());
+        OpenFlowSwitch sw = controller.getSwitch(dpid);
+
+        Set<FlowRule> flowRuleSet = new HashSet<>();
+        if (sw.softwareDescription().equals("OF-DPA 2.0")) {
+            flowRuleSet = createOfdpaFlowRules(serviceId, ceVlanId, vlanId, ingress, egress, first, last);
+            //createFilteringForwarding(serviceId, ceVlanId, vlanId, ingress, egress, first, last);
+        } else if (sw.factory().getVersion() == OFVersion.OF_13) {
+            flowRuleSet = createOF13FlowRule(serviceId, ceVlanId, vlanId, ingress, egress, first, last);
+        } else {
+            flowRuleSet = createOF10FlowRule(serviceId, ceVlanId, vlanId, ingress, egress, first, last);
+        }
+
+        return flowRuleSet;
+    }
+
+    /**
+     * Directly creates FlowRules according to the OFDPA pipeline.
+     * To be used instead of FlowObjectives until the OFDPA2Pipeline is modified appropriately
+     *
+     * @param serviceId User-provided identifier of the CE service
+     * @param vlanId VLAN id of the service
+     * @param ingress ingress connect point at the particular device
+     * @param first indicates whether the current device is the first one in the path
+     * @param last indicates whether the current device is the last one in the path
+     */
+    private Set<FlowRule> createOfdpaFlowRules(String serviceId, VlanId ceVlanId, VlanId vlanId,
+                                               ConnectPoint ingress, ConnectPoint egress, boolean first, boolean last) {
+
+        Set<FlowRule> flowRuleSet = new HashSet<>();
+
+        DeviceId deviceId = egress.deviceId();
+
+        // VLAN Table
+        // "Vlan Assignment"
+
+        TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
+                .matchInPort(ingress.port());
+
+        TrafficSelector.Builder preSelector = null;
+        TrafficTreatment.Builder preTreatment = null;
+
+        // Transition to TMAC table
+        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
+                .transition(TMAC_TABLE);
+
+        if (first) {
+            // If this is a virtual service, match also on CE-VLAN ID at first hop
+            if (ceVlanId != null) {
+                OfdpaMatchVlanVid ofdpaMatchVlanVid = new OfdpaMatchVlanVid(ceVlanId);
+                sBuilder.extension(ofdpaMatchVlanVid, deviceId);
+                OfdpaSetVlanVid ofdpaSetVlanVid = new OfdpaSetVlanVid(vlanId);
+                tBuilder.extension(ofdpaSetVlanVid, deviceId);
+            } else {
+                OfdpaMatchVlanVid ofdpaMatchVlanVid = new OfdpaMatchVlanVid(VlanId.vlanId((short) 0));
+                sBuilder.extension(ofdpaMatchVlanVid, deviceId);
+                OfdpaSetVlanVid ofdpaSetVlanVid = new OfdpaSetVlanVid(vlanId);
+                tBuilder.extension(ofdpaSetVlanVid, deviceId);
+                // XXX ofdpa will require an additional vlan match on the assigned vlan
+                // and it may not require the push. This is not in compliance with OF
+                // standard. Waiting on what the exact flows are going to look like.
+                preSelector = DefaultTrafficSelector.builder();
+                preSelector.matchInPort(ingress.port());
+                OfdpaMatchVlanVid preOfdpaMatchVlanVid = new OfdpaMatchVlanVid(vlanId);
+                preSelector.extension(preOfdpaMatchVlanVid, deviceId);
+                preTreatment = DefaultTrafficTreatment.builder().transition(20);
+            }
+        } else {
+            OfdpaMatchVlanVid ofdpaMatchVlanVid = new OfdpaMatchVlanVid(vlanId);
+            sBuilder.extension(ofdpaMatchVlanVid, deviceId);
+        }
+
+        FlowRule flowRule = createFlowRule(deviceId, PRIORITY, sBuilder.build(), tBuilder.build(), VLAN_TABLE);
+        flowRuleService.applyFlowRules(flowRule);
+        flowRuleSet.add(flowRule);
+
+        if (preSelector != null) {
+
+            flowRule = createFlowRule(deviceId, PRIORITY, preSelector.build(), preTreatment.build(), VLAN_TABLE);
+            flowRuleService.applyFlowRules(flowRule);
+            flowRuleSet.add(flowRule);
+        }
+
+        // TMAC Table defaults to Bridging Table
+
+        // Build group
+        GroupId groupId = createGroup(serviceId, vlanId, egress, first, last);
+
+        // ACL Table
+        // "IPv4 VLAN"
+
+        // NOTE: Directly adding vlanId match to builder causes rule to get continuously installed/uninstalled by ofdpa
+        sBuilder = DefaultTrafficSelector.builder()
+                .matchInPort(ingress.port())
+                .matchEthType(Ethernet.TYPE_IPV4);
+        //sBuilder.extension(new OfdpaMatchVlanVid(vlanId), deviceId);
+
+        // TODO: Check if there is existing FlowRule with same filtering and if yes modify this rule with an extra group
+        // TODO: NOTE: In OFDPA this probably will be done by first removing the existing flow
+
+        tBuilder = DefaultTrafficTreatment.builder().group(groupId);
+
+        flowRule = createFlowRule(deviceId, PRIORITY, sBuilder.build(), tBuilder.build(), ACL_TABLE);
+        flowRuleService.applyFlowRules(flowRule);
+        flowRuleSet.add(flowRule);
+
+        return flowRuleSet;
+    }
+
+    // Directly creates FlowRules using GROUP action (meant for OF1.3 non-OFDPA devices)
+    private Set<FlowRule> createOF13FlowRule(String serviceId, VlanId ceVlanId, VlanId vlanId,
+                                         ConnectPoint ingress, ConnectPoint egress,
+                                         boolean first, boolean last) {
+
+        Set<FlowRule> flowRuleSet = new HashSet<>();
+
+        TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
+                .matchInPort(ingress.port());
+
+        TrafficTreatment.Builder tBuilder;
+        if (first) {
+            // If this is a virtual service, match also on CE-VLAN ID at first hop
+            if (ceVlanId != null) {
+                sBuilder.matchVlanId(ceVlanId);
+            }
+            tBuilder = DefaultTrafficTreatment.builder();
+            tBuilder.pushVlan().setVlanId(vlanId);
+        } else {
+            sBuilder.matchVlanId(vlanId);
+            tBuilder = DefaultTrafficTreatment.builder();
+        }
+
+        // Build group
+        GroupId groupId = createGroup(serviceId, vlanId, egress, first, last);
+        tBuilder.group(groupId);
+
+        // Check if flow with same selector already exists. If yes, modify existing flow rule if needed
+        flowRuleService.getFlowRulesById(appId).forEach(flowRule -> {
+            if (flowRule.deviceId().equals(egress.deviceId()) && flowRule.selector().equals(sBuilder.build())) {
+                flowRule.treatment().allInstructions().forEach(instruction -> {
+                    // If this is an GROUP instruction and group is different than existing, add the group
+                    if (instruction.type() == Instruction.Type.GROUP &&
+                            !(instruction.equals(Instructions.createGroup(groupId)))) {
+                        tBuilder.add(instruction);
+                    }
+                });
+            }
+        });
+
+        // FIXME: For efficiency do not send FlowMod again if the new treatment is exactly the same as the existing one
+        FlowRule flowRule = createFlowRule(egress.deviceId(), PRIORITY, sBuilder.build(), tBuilder.build(), 0);
+        flowRuleService.applyFlowRules(flowRule);
+        flowRuleSet.add(flowRule);
+
+        return flowRuleSet;
+    }
+
+    // Directly creates FlowRules using OUTPUT action (meant for OF1.0 non-OFDPA devices)
+    private Set<FlowRule> createOF10FlowRule(String serviceId, VlanId ceVlanId, VlanId vlanId,
+                                         ConnectPoint ingress, ConnectPoint egress,
+                                         boolean first, boolean last) {
+
+        Set<FlowRule> flowRuleSet = new HashSet<>();
+
+        TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
+                .matchInPort(ingress.port());
+
+        TrafficTreatment.Builder tBuilder;
+        if (first) {
+            // If this is a virtual service, match also on CE-VLAN ID at first hop
+            if (ceVlanId != null) {
+                sBuilder.matchVlanId(ceVlanId);
+            }
+            tBuilder = DefaultTrafficTreatment.builder();
+            tBuilder.pushVlan().setVlanId(vlanId);
+        } else {
+            sBuilder.matchVlanId(vlanId);
+            tBuilder = DefaultTrafficTreatment.builder();
+        }
+
+        if (last) {
+            tBuilder.popVlan();
+        }
+        tBuilder.setOutput(egress.port());
+
+        // Check if flow with same selector already exists. If yes, modify existing flow rule if needed
+        flowRuleService.getFlowRulesById(appId).forEach(flowRule -> {
+            if (flowRule.deviceId().equals(egress.deviceId()) && flowRule.selector().equals(sBuilder.build())) {
+                flowRule.treatment().allInstructions().forEach(instruction -> {
+                    // If this is an OUTPUT instruction and output is different than existing, add the group
+                    if (instruction.type() == Instruction.Type.OUTPUT &&
+                            !(instruction.equals(Instructions.createOutput(egress.port())))) {
+                        tBuilder.add(instruction);
+                    }
+                });
+            }
+        });
+
+        // FIXME: For efficiency do not send FlowMod again if the new treatment is exactly the same as the existing one
+        FlowRule flowRule = createFlowRule(egress.deviceId(), PRIORITY, sBuilder.build(), tBuilder.build(), 0);
+        flowRuleService.applyFlowRules(flowRule);
+        flowRuleSet.add(flowRule);
+
+        return flowRuleSet;
+    }
+
+    /**
+     * Creates and submits FilteringObjective and ForwardingObjective with INDIRECT groups based on the role of the.
+     * specific device within the path.
+     *
+     * @param serviceId User-provided identifier of the CE service
+     * @param ceVlanId CE-VLAN id of the service, if present
+     * @param vlanId VLAN id of the service
+     * @param ingress ingress connect point at the particular device
+     * @param first indicates whether the current device is the first one in the path
+     * @param last indicates whether the current device is the last one in the path
+     */
+    private void createFilteringForwarding(String serviceId, VlanId ceVlanId, VlanId vlanId,
+                                           ConnectPoint ingress, ConnectPoint egress,
+                                           boolean first, boolean last) {
+
+        createFilteringObjective(ceVlanId, vlanId, ingress, first);
+        createForwardingObjective(serviceId, vlanId, ingress, egress, first, last);
+    }
+
+    /**
+     * Creates and submits FilteringObjective based on the role of the specific device within the path.
+     *
+     * @param ceVlanId the CE-VLAN id of the service, if present
+     * @param vlanId VLAN id of the service
+     * @param ingress ingress connect point at the particular device
+     * @param first indicates whether the current device is the first one in the path
+     */
+    private void createFilteringObjective(VlanId ceVlanId, VlanId vlanId, ConnectPoint ingress, boolean first) {
+
+        FilteringObjective.Builder fob = DefaultFilteringObjective.builder();
+        TrafficTreatment.Builder ttb = DefaultTrafficTreatment.builder();
+
+        fob.withKey(Criteria.matchInPort(ingress.port()));
+        if (first) {
+            // If this is a virtual service, match also on CE-VLAN ID at first hop
+            if (ceVlanId != null) {
+                fob.addCondition(Criteria.matchVlanId(ceVlanId));
+            } else {
+                fob.addCondition(Criteria.matchVlanId(VlanId.NONE));
+            }
+            ttb.pushVlan().setVlanId(vlanId);
+        } else {
+            fob.addCondition(Criteria.matchVlanId(vlanId));
+        }
+
+        fob.withPriority(PRIORITY);
+        fob.withMeta(ttb.build());
+        fob.permit().fromApp(appId);
+
+        flowObjectiveService.filter(ingress.deviceId(), fob.add());
+
+    }
+
+    /**
+     * Creates and submits ForwardingObjective based on the role of the specific device within the path.
+     *
+     * @param serviceId the CE service id
+     * @param vlanId VLAN id of the service
+     * @param ingress ingress connect point at the particular device
+     * @param egress egress connect point at the particular device
+     * @param first indicates whether the current device is the first one in the path
+     * @param last indicates whether the current device is the last one in the path
+     */
+    private void createForwardingObjective(String serviceId, VlanId vlanId, ConnectPoint ingress, ConnectPoint egress,
+                                           boolean first, boolean last) {
+
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchVlanId(vlanId)
+                .matchInPort(ingress.port())
+                .matchEthType(Ethernet.TYPE_IPV4)
+                .build();
+
+        GroupId groupId = createGroup(serviceId, vlanId, egress, first, last);
+
+        // Add group to original treatment
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder().group(groupId).build();
+
+        ForwardingObjective forwardingObjective = DefaultForwardingObjective.builder()
+                .fromApp(appId)
+                .makePermanent()
+                .withFlag(ForwardingObjective.Flag.VERSATILE)
+                .withPriority(PRIORITY)
+                .withSelector(selector)
+                .withTreatment(treatment)
+                .add();
+
+        flowObjectiveService.forward(ingress.deviceId(), forwardingObjective);
+    }
+
+    /**
+     * Creates INDIRECT group with single bucket and submits it to GroupService.
+     *
+     * @param serviceId User-provided identifier of the CE service
+     * @param vlanId VLAN id of the service
+     * @param egress egress connect point at the particular device
+     * @param first indicates whether the current device is the first one in the path
+     * @param last indicates whether the current device is the last one in the path
+     * @return The GroupId of the created Group
+     */
+    private GroupId createGroup(String serviceId, VlanId vlanId, ConnectPoint egress, boolean first, boolean last) {
+
+        checkNotNull(serviceId);
+
+        DeviceId deviceId = egress.deviceId();
+
+        GroupKey groupKey = getGroupKey(vlanId, egress);
+        Group group = groupService.getGroup(deviceId, groupKey);
+        GroupId groupId = getGroupId(vlanId, egress);
+
+        if (group != null) {
+            log.warn("Group {} already exists in {}", groupKey.toString(), deviceId);
+            return groupId;
+        }
+
+        GroupBuckets buckets = getGroupBuckets(egress, last);
+
+        GroupDescription groupDescription = new DefaultGroupDescription(
+                deviceId,
+                GroupDescription.Type.INDIRECT,
+                buckets,
+                groupKey,
+                groupId.id(),
+                appId);
+
+        groupService.addGroup(groupDescription);
+
+        return groupId;
+    }
+
+    /**
+     * Currently creates single group bucket to be used instead of an OUTPUT action.
+     *
+     * @param egress egress connect point at the particular device
+     * @param last indicates whether the current device is the last one in the path
+     * @return GroupBuckets which can be used to create a GroupDescription
+     */
+    private GroupBuckets getGroupBuckets(ConnectPoint egress, boolean last) {
+
+        List<GroupBucket> buckets = Lists.newArrayList();
+
+        TrafficTreatment.Builder treatmentBuilder;
+        if (last) {
+            treatmentBuilder = DefaultTrafficTreatment.builder();
+            treatmentBuilder.popVlan();
+        } else {
+            treatmentBuilder = DefaultTrafficTreatment.builder();
+        }
+        TrafficTreatment treatment = treatmentBuilder.setOutput(egress.port()).build();
+
+        buckets.add(DefaultGroupBucket.createIndirectGroupBucket(treatment));
+
+        return new GroupBuckets(buckets);
+    }
+
+    /**
+     * Returns globally unique group id according to OFDPA 2.0 specification for "L2 Interface" group types.
+     *
+     * @param vlanId VLAN id of the service
+     * @param egress egress connect point at the particular device
+     * @return group id
+     */
+    private GroupId getGroupId(VlanId vlanId, ConnectPoint egress) {
+        return new DefaultGroupId((vlanId.toShort()) << 16 | Integer.parseInt(egress.port().toString()));
+    }
+
+    /**
+     * Returns globally unique group key.
+     *
+     * @param vlanId VLAN id of the service
+     * @param egress egress connect point at the particular device
+     * @return group key
+     */
+    private GroupKey getGroupKey(VlanId vlanId, ConnectPoint egress) {
+        //TODO: Create GroupKey in a better way - perhaps the same as GroupId (unique per device)
+        return new DefaultGroupKey(Integer.toString(Objects.hash(egress.deviceId(), egress.port(), vlanId)).getBytes());
+    }
+
+    @Override
+    void applyBandwidthProfileResources(String serviceId, CarrierEthernetUni uni) {
+
+        Dpid dpid = Dpid.dpid(uni.cp().deviceId().uri());
+        OpenFlowSwitch sw = controller.getSwitch(dpid);
+
+        // FIXME: Temporary hack: Do not apply meters to OFDPA2.0 switches
+        if (sw.softwareDescription().equals("OF-DPA 2.0")) {
+            return;
+        }
+
+        // Create meters and add them to global MeterId map
+        Set<DeviceMeterId> deviceMeterIdSet = deviceMeterIdMap.get(serviceId);
+        if (deviceMeterIdSet == null) {
+            deviceMeterIdSet = new HashSet<>();
+        }
+        deviceMeterIdSet.addAll(createMeters(uni));
+        deviceMeterIdMap.put(serviceId, deviceMeterIdSet);
+
+        // Apply meters to already installed flows
+
+        Set<FlowRule> newFlowRuleSet = new HashSet<>();
+
+        // Get flow rules belonging to service and having as in_port the UNI connect point
+        flowRuleMap.get(serviceId).forEach(flowRule -> {
+            PortNumber inPort = ((PortCriterion) flowRule.selector().getCriterion(Criterion.Type.IN_PORT)).port();
+            ConnectPoint flowInCp = new ConnectPoint(flowRule.deviceId(), inPort);
+            //VlanId flowInVlanId = ((VlanIdCriterion) flowRule.selector().
+            //        getCriterion(Criterion.Type.VLAN_VID)).vlanId();
+            // TODO: Compare also to the CE-VLAN ID (if it is not null)
+            // FIXME: Maybe check only in_port, vlanid, and if there is output port or group action?
+            if (uni.cp().equals(flowInCp)) {
+            //if (uni.cp().equals(flowInCp) && (uni.ceVlanId() == null || uni.ceVlanId().equals(flowInVlanId))) {
+                // Need to add to the flow the meters associated with the same device
+                Set<DeviceMeterId> tmpDeviceMeterIdSet = new HashSet<>();
+                deviceMeterIdMap.get(serviceId).forEach(deviceMeterId -> {
+                    if (deviceMeterId.deviceId().equals(flowRule.deviceId())) {
+                        tmpDeviceMeterIdSet.add(deviceMeterId);
+                    }
+                });
+                // Modify and submit flow rule only if there are meters to add
+                if (!tmpDeviceMeterIdSet.isEmpty()) {
+                    FlowRule newFlowRule = addMetersToFlowRule(flowRule, tmpDeviceMeterIdSet);
+                    flowRuleService.applyFlowRules(newFlowRule);
+                    newFlowRuleSet.add(newFlowRule);
+                } else {
+                    newFlowRuleSet.add(flowRule);
+                }
+            } else {
+                newFlowRuleSet.add(flowRule);
+            }
+        });
+
+        flowRuleMap.put(serviceId, newFlowRuleSet);
+    }
+
+    /**
+     * Creates and submits a meter with the required bands for a UNI.
+     *
+     * @param uni the UNI descriptor
+     * @return set of meter ids of the meters created
+     */
+    private Set<DeviceMeterId> createMeters(CarrierEthernetUni uni) {
+
+        // TODO: Check if meter already exists before adding it?
+
+        Set<DeviceMeterId> deviceMeterIdSet = new HashSet<>();
+
+        long longCir = (long) (uni.bwp().cir().bps() / 8000);
+        long longEir = (long) (uni.bwp().eir().bps() / 8000);
+
+        MeterRequest.Builder meterRequestBuilder;
+        Meter meter;
+        Band.Builder bandBuilder;
+
+        Set<Band> bandSet = new HashSet<>();
+
+        // If EIR is zero do not create the REMARK meter
+        if (longEir != 0) {
+            // Mark frames that exceed CIR as Best Effort
+            bandBuilder = DefaultBand.builder()
+                    .ofType(Band.Type.REMARK)
+                    .withRate(longCir)
+                    .dropPrecedence((short) 0);
+
+            if (uni.bwp().cbs() != 0) {
+                bandBuilder.burstSize(uni.bwp().cbs());
+            }
+
+            bandSet.add(bandBuilder.build());
+        }
+
+        // If CIR is zero do not create the DROP meter
+        if (longCir != 0) {
+            // Drop all frames that exceed CIR + EIR
+            bandBuilder = DefaultBand.builder()
+                    .ofType(Band.Type.DROP)
+                    .withRate(longCir + longEir);
+
+            if (uni.bwp().cbs() != 0 || uni.bwp().ebs() != 0) {
+                // FIXME: Use CBS and EBS correctly according to MEF specs
+                bandBuilder.burstSize(uni.bwp().cbs() + uni.bwp().ebs());
+            }
+
+            bandSet.add(bandBuilder.build());
+        }
+
+        // Create meter only if at least one band was created
+        if (!bandSet.isEmpty()) {
+            meterRequestBuilder = DefaultMeterRequest.builder()
+                    .forDevice(uni.cp().deviceId())
+                    .fromApp(appId)
+                    .withUnit(Meter.Unit.KB_PER_SEC)
+                    .withBands(bandSet);
+
+            if (uni.bwp().cbs() != 0 || uni.bwp().ebs() != 0) {
+                meterRequestBuilder.burst();
+            }
+
+            meter = meterService.submit(meterRequestBuilder.add());
+            deviceMeterIdSet.add(new DeviceMeterId(uni.cp().deviceId(), meter.id()));
+        }
+
+        return deviceMeterIdSet;
+    }
+
+    private FlowRule addMeterToFlowRule(FlowRule flowRule, DeviceMeterId deviceMeterId) {
+
+        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment
+                .builder(flowRule.treatment());
+
+        tBuilder.add(Instructions.meterTraffic(deviceMeterId.meterId()));
+
+        return createFlowRule(flowRule.deviceId(), flowRule.priority(),
+                flowRule.selector(), tBuilder.build(), flowRule.tableId());
+    }
+
+    private FlowRule addMetersToFlowRule(FlowRule flowRule, Set<DeviceMeterId> deviceMeterIdSet) {
+
+        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment
+                .builder(flowRule.treatment());
+
+        deviceMeterIdSet.forEach(deviceMeterId -> {
+            //tBuilder.add(Instructions.meterTraffic(deviceMeterId.meterId()));
+            tBuilder.meter(deviceMeterId.meterId());
+        });
+
+        return createFlowRule(flowRule.deviceId(), flowRule.priority(),
+                flowRule.selector(), tBuilder.build(), flowRule.tableId());
+    }
+
+    @Override
+    void removeBandwidthProfileResources(String serviceId, CarrierEthernetUni uni) {
+
+        removeMeters(serviceId, uni);
+    }
+
+    /**
+     * Removes the meters associated with a specific UNI of a service.
+     *
+     * @param serviceId the CE service ID
+     * @param uni the UNI descriptor
+     * */
+    private void removeMeters(String serviceId, CarrierEthernetUni uni) {
+
+        Set<DeviceMeterId> newDeviceMeterIdSet = deviceMeterIdMap.get(serviceId);
+        DeviceMeterId tmpDeviceMeterId;
+
+        Collection<Meter> meters = meterService.getMeters(uni.cp().deviceId());
+
+        Iterator<Meter> it = meters.iterator();
+        while (it.hasNext()) {
+            Meter meter = it.next();
+            tmpDeviceMeterId = new DeviceMeterId(uni.cp().deviceId(), meter.id());
+            if (meter.appId().equals(appId) &&
+                    deviceMeterIdMap.get(serviceId).contains(tmpDeviceMeterId)) {
+                MeterRequest.Builder mBuilder;
+                mBuilder = DefaultMeterRequest.builder()
+                        .fromApp(meter.appId())
+                        .forDevice(meter.deviceId())
+                        .withUnit(meter.unit())
+                        .withBands(meter.bands());
+                if (uni.bwp().cbs() != 0 || uni.bwp().ebs() != 0) {
+                    mBuilder.burst();
+                }
+                meterService.withdraw(mBuilder.remove(), meter.id());
+                newDeviceMeterIdSet.remove(tmpDeviceMeterId);
+            }
+        }
+
+        deviceMeterIdMap.put(serviceId, newDeviceMeterIdSet);
+    }
+
+    @Override
+    void removeAllForwardingResources(CarrierEthernetService service) {
+        removeFlowRules(service.id());
+        removeGroups(service);
+    }
+
+    /**
+     * Removes all flow rules installed by the application which are associated with a specific CE service.
+     *
+     * @param serviceId the CE service id
+     * */
+    private void removeFlowRules(String serviceId) {
+        // Note: A Flow Rule cannot be shared by multiple services due to different VLAN or CE-VLAN ID match.
+        Set<FlowRule> flowRuleSet = flowRuleMap.remove(serviceId);
+        flowRuleSet.forEach(flowRule -> flowRuleService.removeFlowRules(flowRule));
+    }
+
+    /**
+     * Removes all groups installed by the application which are associated with a specific CE service.
+     *
+     * @param service the CE service definition
+     * */
+    // Note: A Group cannot be shared by multiple services since GroupIds/GroupKeys include the service VLAN ID
+    private void removeGroups(CarrierEthernetService service) {
+
+        Set<ConnectPoint> egressCpSet = egressCpMap.remove(service.id());
+        Set<ConnectPoint> uniCpSet = new HashSet<>();
+
+        service.uniSet().forEach(uni -> uniCpSet.add(uni.cp()));
+
+        egressCpSet.forEach(egress -> {
+            // The connect points associated with UNIs are the ones including the VLAN pop commands, i.e. the "last"
+            boolean last = (uniCpSet.contains(egress));
+            DeviceId deviceId = egress.deviceId();
+            GroupKey groupKey = getGroupKey(service.vlanId(), egress);
+            GroupBuckets buckets = getGroupBuckets(egress, last);
+            if (groupService.getGroup(deviceId, groupKey) != null) {
+                // Note: Removing buckets before removing group in CpQD causes warnings (but is needed in OFDPA2.0)
+                Dpid dpid = Dpid.dpid(deviceId.uri());
+                OpenFlowSwitch sw = controller.getSwitch(dpid);
+                if (sw.softwareDescription().equals("OF-DPA 2.0")) {
+                    groupService.removeBucketsFromGroup(
+                            deviceId,
+                            groupKey,
+                            buckets,
+                            groupKey,
+                            appId);
+                }
+                log.info("Trying to remove group with key {} from {}", groupKey, deviceId);
+                groupService.removeGroup(deviceId, groupKey, appId);
+            }
+        });
+    }
+
+    /**
+     * Utility class to compensate for the fact that MeterIds are not unique system-wide.
+     * */
+    class DeviceMeterId {
+        private DeviceId deviceId;
+        private MeterId meterId;
+
+        DeviceMeterId(DeviceId deviceId, MeterId meterId) {
+            this.deviceId = deviceId;
+            this.meterId = meterId;
+        }
+
+        public DeviceId deviceId() {
+            return deviceId;
+        }
+
+        public MeterId meterId() {
+            return meterId;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(deviceId, meterId);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj instanceof DeviceMeterId) {
+                DeviceMeterId other = (DeviceMeterId) obj;
+                if (this.deviceId().equals(other.deviceId()) && this.meterId().equals(other.meterId())) {
+                    return true;
+                }
+            }
+            return false;
+        }
+    }
+
+    private FlowRule createFlowRule(DeviceId deviceId, int priority,
+                                    TrafficSelector selector, TrafficTreatment treatment, int tableId) {
+        return DefaultFlowRule.builder()
+                .fromApp(appId)
+                .forDevice(deviceId)
+                .makePermanent()
+                .withPriority(priority)
+                .withSelector(selector)
+                .withTreatment(treatment)
+                .forTable(tableId)
+                .build();
+    }
+
+}
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetPacketNodeManager.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetPacketNodeManager.java
new file mode 100644
index 0000000..3b2b771
--- /dev/null
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetPacketNodeManager.java
@@ -0,0 +1,35 @@
+/*
+ * 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.ecord.carrierethernet.app;
+
+import org.onosproject.net.ConnectPoint;
+
+/**
+ * Abstraction of a class used to control Carrier Ethernet nodes according to their control protocol.
+ */
+public abstract class CarrierEthernetPacketNodeManager {
+
+    abstract void setNodeForwarding(CarrierEthernetService service, CarrierEthernetUni srcUni,
+                                    CarrierEthernetUni dstUni, ConnectPoint ingress, ConnectPoint egress,
+                                    boolean first, boolean last);
+
+    abstract void applyBandwidthProfileResources(String serviceId, CarrierEthernetUni uni);
+
+    abstract void removeBandwidthProfileResources(String serviceId, CarrierEthernetUni uni);
+
+    abstract void removeAllForwardingResources(CarrierEthernetService service);
+
+}
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetPacketProvisioner.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetPacketProvisioner.java
new file mode 100644
index 0000000..a2d993a
--- /dev/null
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetPacketProvisioner.java
@@ -0,0 +1,190 @@
+/*
+ * 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.ecord.carrierethernet.app;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onosproject.net.Device;
+import org.onosproject.net.Link;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Path;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.intent.Constraint;
+import org.onosproject.net.intent.constraint.BandwidthConstraint;
+import org.onosproject.net.intent.constraint.LatencyConstraint;
+import org.onosproject.net.topology.PathService;
+import org.slf4j.Logger;
+
+import java.util.Set;
+import java.util.List;
+import java.util.ArrayList;
+
+import static org.onosproject.net.DefaultEdgeLink.createEdgeLink;
+import static org.slf4j.LoggerFactory.getLogger;
+
+@Component(immediate = true)
+@Service (value = CarrierEthernetPacketProvisioner.class)
+public class CarrierEthernetPacketProvisioner {
+
+    private final Logger log = getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected PathService pathService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CarrierEthernetOpenFlowPacketNodeManager ceOfPktNodeManager;
+
+    @Activate
+    protected void activate() {}
+
+    @Deactivate
+    protected void deactivate() {
+
+    }
+
+    public boolean setupConnectivity(CarrierEthernetUni uni1, CarrierEthernetUni uni2, CarrierEthernetService service) {
+
+        // Find the paths for both directions at the same time, so that we can skip the pair if needed
+        List<Link> forwardLinks = selectLinkPath(uni1, uni2, service);
+        List<Link> backwardLinks = selectLinkPath(uni2, uni1, service);
+
+        // Skip this UNI pair if no feasible path could be found
+        if (forwardLinks == null || (!service.congruentPaths() && backwardLinks == null)) {
+            log.warn("There are no feasible paths between {} and {}.",
+                    uni1.cp().deviceId(), uni2.cp().deviceId());
+            return false;
+        }
+
+        // Establish connectivity for the packet switches
+        // TODO: Send some kind of gRPC message to BigSwitches
+        for (int i = 0; i < forwardLinks.size() - 1; i++) {
+            // Create flows for the forward direction
+            boolean first = isFirst(i);
+            boolean last = isLast(forwardLinks, i);
+            ConnectPoint ingress = forwardLinks.get(i).dst();
+            ConnectPoint egress = forwardLinks.get(i + 1).src();
+            //  TODO: Select node manager depending on device protocol
+            // Set forwarding only on packet switches
+            if (deviceService.getDevice(ingress.deviceId()).type().equals(Device.Type.SWITCH)) {
+                ceOfPktNodeManager.setNodeForwarding(service, uni1, uni2, ingress, egress, first, last);
+            }
+
+            if (service.congruentPaths()) {
+                // Create flows for the forward direction using the reverse path
+                ingress = forwardLinks.get(forwardLinks.size() - i - 1).src();
+                egress = forwardLinks.get(forwardLinks.size() - i - 2).dst();
+                //  TODO: Select node manager depending on device protocol
+                if (deviceService.getDevice(ingress.deviceId()).type().equals(Device.Type.SWITCH)) {
+                    ceOfPktNodeManager.setNodeForwarding(service, uni2, uni1, ingress, egress, first, last);
+                }
+            }
+        }
+
+        if (!service.congruentPaths()) {
+            // Create flows for the backward direction using a path potentially different from the reverse one
+            for (int i = 0; i < backwardLinks.size() - 1; i++) {
+                boolean first = isFirst(i);
+                boolean last = isLast(backwardLinks, i);
+                ConnectPoint ingress = backwardLinks.get(i).dst();
+                ConnectPoint egress = backwardLinks.get(i + 1).src();
+                //  TODO: Select node manager depending on device protocol
+                if (deviceService.getDevice(ingress.deviceId()).type().equals(Device.Type.SWITCH)) {
+                    ceOfPktNodeManager.setNodeForwarding(service, uni2, uni1, ingress, egress, first, last);
+                }
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Select a feasible link path between two UNIs based on the CE service parameters.
+     *
+     * @param uni1 the first UNI
+     * @param uni2 the second UNI
+     * @param service the CE service descriptor
+     */
+    private List<Link> selectLinkPath(CarrierEthernetUni uni1, CarrierEthernetUni uni2,
+                                      CarrierEthernetService service) {
+
+        List<Constraint> constraints = ImmutableList.<Constraint>builder()
+                .add(new BandwidthConstraint(uni1.bwp().cir()))
+                .add(new LatencyConstraint(service.latency()))
+                .build();
+
+        Set<Path> paths = pathService.getPaths(uni1.cp().deviceId(), uni2.cp().deviceId());
+
+        Path path = null;
+
+        for (Path p : paths) {
+            // TODO: Select path in more sophisticated way and return null if any of the constraints cannot be met
+            path = p;
+            break;
+        }
+
+        if (path == null) {
+            return null;
+        } else {
+            List<Link> links = new ArrayList<>();
+            links.add(createEdgeLink(uni1.cp(), true));
+            links.addAll(path.links());
+            links.add(createEdgeLink(uni2.cp(), false));
+            return links;
+        }
+    }
+
+    private boolean isLast(List<Link> links, int i) {
+        return i == links.size() - 2;
+    }
+
+    private boolean isFirst(int i) {
+        return i == 0;
+    }
+
+    public void removeConnectivity(CarrierEthernetService service) {
+        // TODO: Add here the same call for all node manager types
+        ceOfPktNodeManager.removeAllForwardingResources(service);
+    }
+
+    /**
+     * Applies bandwidth profiles to the UNIs of a service.
+     *
+     * @param service the CE service definition
+     */
+    public void applyBandwidthProfiles(CarrierEthernetService service) {
+        //  TODO: Select node manager depending on device protocol
+        service.uniSet().forEach(uni -> ceOfPktNodeManager.applyBandwidthProfileResources(service.id(), uni));
+    }
+
+    /**
+     * Removes bandwidth profiles from the UNIs of a service.
+     *
+     * @param service the CE service definition
+     */
+    public void removeBandwidthProfiles(CarrierEthernetService service) {
+        //  TODO: Select node manager depending on device protocol
+        service.uniSet().forEach(uni -> ceOfPktNodeManager.removeBandwidthProfileResources(service.id(), uni));
+    }
+
+}
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetService.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetService.java
new file mode 100644
index 0000000..f688768
--- /dev/null
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetService.java
@@ -0,0 +1,261 @@
+/*
+ * 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.ecord.carrierethernet.app;
+
+import org.onlab.packet.VlanId;
+import org.onosproject.ecord.metro.api.MetroConnectivityId;
+import org.onosproject.ecord.metro.api.MetroPathEvent;
+
+import java.time.Duration;
+import java.util.HashSet;
+import java.util.Set;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Representation of a Carrier Ethernet Service along with relevant ONOS-related resources.
+ */
+public class CarrierEthernetService {
+
+    public enum Type {
+        POINT_TO_POINT, MULTIPOINT_TO_MULTIPOINT, ROOT_MULTIPOINT
+    }
+
+    protected String serviceId;
+    protected String serviceCfgId;
+    protected Type serviceType;
+    protected VlanId vlanId;
+    protected boolean isVirtual;
+    protected Set<CarrierEthernetUni> uniSet;
+    protected Duration latency;
+    protected CarrierEthernetServiceMetroConnectivity metroConnectivity;
+    protected boolean congruentPaths;
+
+    // Set to true if both directions should use the same path
+    private static final boolean CONGRUENT_PATHS = true;
+
+    private static final Duration DEFAULT_LATENCY = Duration.ofMillis(50);
+
+    // Note: serviceId should be provided only when updating an existing service
+    public CarrierEthernetService(String serviceId, String serviceCfgId, Type serviceType,
+                                  Set<CarrierEthernetUni> uniSet) {
+        this.serviceId = serviceId;
+        this.serviceCfgId = serviceCfgId;
+        this.serviceType = serviceType;
+        this.vlanId = null;
+        this.uniSet = new HashSet<>();
+        this.uniSet.addAll(uniSet);
+        this.congruentPaths = CONGRUENT_PATHS;
+        this.latency = DEFAULT_LATENCY;
+        this.metroConnectivity = new CarrierEthernetServiceMetroConnectivity(null, MetroPathEvent.Type.PATH_REMOVED);
+    }
+
+    /**
+     * Returns service identifier.
+     *
+     * @return service identifier
+     */
+    public String id() {
+        return serviceId;
+    }
+
+    /**
+     * Returns service config identifier.
+     *
+     * @return service config identifier
+     */
+    public String cfgId() {
+        return serviceCfgId;
+    }
+
+    /**
+     * Returns type of service.
+     *
+     * @return type of service
+     */
+    public Type type() {
+        return serviceType;
+    }
+
+    /**
+     * Returns Vlan id.
+     *
+     * @return Vlan id
+     */
+    public VlanId vlanId() {
+        return vlanId;
+    }
+
+    /**
+     * Returns the Virtual status of the service (i.e. if all UNIs have CE-VLAN ids).
+     *
+     * @return true if service is virtual, false otherwise
+     */
+    public boolean isVirtual() {
+        return isVirtual;
+    }
+
+    /**
+     * Returns set of UNIs.
+     *
+     * @return set of UNIs
+     */
+    public Set<CarrierEthernetUni> uniSet() {
+        return uniSet;
+    }
+
+    /**
+     * Returns latency constraint.
+     *
+     * @return latency constraint
+     */
+    public Duration latency() {
+        return latency;
+    }
+
+    /**
+     * Returns true if service requires congruent paths.
+     *
+     * @return true if congruent paths required
+     */
+    public boolean congruentPaths() {
+        return congruentPaths;
+    }
+
+    /**
+     * Sets service identifier.
+     *
+     * @param serviceId the service identifier to set
+     */
+    public void setId(String serviceId) {
+        this.serviceId = serviceId;
+    }
+
+    /**
+     * Sets service config identifier.
+     *
+     * @param serviceCfgId service config identifier
+     */
+    public void setCfgId(String serviceCfgId) {
+        this.serviceCfgId = serviceCfgId;
+    }
+
+    /**
+     * Sets the set of UNIs.
+     *
+     * @param uniSet the set of UNIs to be set
+     */
+    public void setUniSet(Set<CarrierEthernetUni> uniSet) {
+        this.uniSet = uniSet;
+    }
+
+    /**
+     * Sets the value of the congruent paths parameter.
+     *
+     * @param congruentPaths the congruent paths parameter value to set
+     */
+    public void setCongruentPaths(boolean congruentPaths) {
+        this.congruentPaths = congruentPaths;
+    }
+
+    /**
+     * Sets the vlanId to be used by the service.
+     *
+     * @param vlanId the vlanId to set
+     */
+    public void setVlanId(VlanId vlanId) {
+        this.vlanId = vlanId;
+    }
+
+    /**
+     * Sets the Virtual status of the service.
+     *
+     * @param isVirtual boolean value with the status to set
+     */
+    public void setIsVirtual(boolean isVirtual) {
+        this.isVirtual = isVirtual;
+    }
+
+    /**
+     * Gets metro connectivity id.
+     *
+     * @return the metro connectivity of the service
+     */
+    public CarrierEthernetServiceMetroConnectivity metroConnectivity() {
+        return this.metroConnectivity;
+    }
+
+    /**
+     * Sets metro connectivity id.
+     *
+     * @param id the metro connectivity identifier to set
+     */
+    public void setMetroConnectivityId(MetroConnectivityId id) {
+        this.metroConnectivity.setId(id);
+    }
+
+    /**
+     * Sets metro connectivity status.
+     *
+     * @param status the metro connectivity status
+     */
+    public void setMetroConnectivityStatus(MetroPathEvent.Type status) {
+        this.metroConnectivity.setStatus(status);
+    }
+
+    public String toString() {
+
+        return toStringHelper(this)
+                .add("id", serviceId)
+                .add("cfgId", serviceCfgId)
+                .add("type", serviceType)
+                .add("vlanId", vlanId)
+                .add("metroConnectId", (metroConnectivity.id() == null ? "null" : metroConnectivity.id().value()))
+                .add("UNIs", uniSet).toString();
+    }
+
+    class CarrierEthernetServiceMetroConnectivity {
+
+        // TODO: In the future this may be replaced by a connectivity intent
+        // FIXME: Need to keep a set of MetroConnectivityIds
+
+        private MetroConnectivityId id;
+        private MetroPathEvent.Type status;
+
+        CarrierEthernetServiceMetroConnectivity(MetroConnectivityId id, MetroPathEvent.Type status) {
+            this.id = id;
+            this.status = status;
+        }
+
+        public MetroConnectivityId id() {
+            return this.id;
+        }
+
+        public MetroPathEvent.Type status() {
+            return this.status;
+        }
+
+        public void setId(MetroConnectivityId id) {
+            this.id = id;
+        }
+
+        public void setStatus(MetroPathEvent.Type status) {
+            this.status = status;
+        }
+
+    }
+
+}
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetUni.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetUni.java
new file mode 100644
index 0000000..d68bd33
--- /dev/null
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetUni.java
@@ -0,0 +1,332 @@
+/*
+ * 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.ecord.carrierethernet.app;
+
+import org.onlab.packet.VlanId;
+import org.onlab.util.Bandwidth;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.device.DeviceService;
+import org.slf4j.Logger;
+
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Representation of a Carrier Ethernet UNI.
+ * Class can be used in different two ways:
+ * 1. As a global UNI descriptor containing one or more BW profiles
+ * 2. As a service-specific UNI descriptor containing a single BW profile and including a type (root, leaf)
+ */
+public class CarrierEthernetUni {
+
+    private final Logger log = getLogger(getClass());
+
+    protected DeviceService deviceService = AbstractShellCommand.get(DeviceService.class);
+
+    public enum Type {
+        ROOT, LEAF
+    }
+
+    protected ConnectPoint connectPoint;
+    protected String uniId;
+    protected String uniCfgId;
+    protected Type type;
+    protected Set<VlanId> ceVlanIdSet;
+    protected Bandwidth capacity;
+    protected Bandwidth usedCapacity;
+
+    // Note: INTERFACE BWP map can only have up to one element
+    protected final Map<CarrierEthernetBandwidthProfile.Type, Map<String, CarrierEthernetBandwidthProfile>> bwpMap =
+            new HashMap<>();
+
+    // TODO: May be needed to add refCount for CoS BWPs - only applicable to global UNIs
+
+    public CarrierEthernetUni(ConnectPoint connectPoint, String uniCfgId, Type type, VlanId ceVlanId,
+                              CarrierEthernetBandwidthProfile bwp) {
+        // TODO: Check for null
+        this.connectPoint = connectPoint;
+        this.uniId = this.connectPoint.deviceId().toString() + "/" + this.connectPoint.port().toString();
+        this.uniCfgId = (uniCfgId == null ? this.uniId : uniCfgId);
+        this.type = type;
+        this.ceVlanIdSet = new HashSet<>();
+        if (ceVlanId != null) {
+            this.ceVlanIdSet.add(ceVlanId);
+        }
+        this.capacity = Bandwidth.mbps(deviceService.getPort(connectPoint.deviceId(), connectPoint.port())
+                .portSpeed());
+        this.usedCapacity = Bandwidth.mbps((double) 0);
+        for (CarrierEthernetBandwidthProfile.Type bwpType : CarrierEthernetBandwidthProfile.Type.values()) {
+            this.bwpMap.put(bwpType, new HashMap<>());
+        }
+
+        if (bwp != null) {
+            // Limit the CIR of the provided bwp according to UNI capacity
+            if (bwp.cir().bps() > this.capacity.bps()) {
+                log.warn("UNI {}: Limiting provided CIR ({} bps) to UNI capacity ({} bps)",
+                        this.uniId, (long) bwp.cir().bps(), this.capacity);
+            }
+            bwp.setCir(Bandwidth.bps(Math.min(bwp.cir().bps(), this.capacity.bps())));
+
+            // Limit the EIR of the provided bwp according to the UNI capacity minus CIR
+            if (bwp.eir().bps() > this.capacity.bps() - bwp.cir().bps()) {
+                log.warn("UNI {}: Limiting provided EIR ({} bps) to UNI capacity minus CIR ({} bps)",
+                        this.uniId, bwp.eir().bps(), this.capacity.bps() - bwp.cir().bps());
+            }
+            bwp.setEir(Bandwidth.bps(Math.min(bwp.eir().bps(), this.capacity.bps() - bwp.cir().bps())));
+
+            addBandwidthProfile(bwp);
+        }
+    }
+
+    /**
+     * Adds the resources associated with a service-specific UNI to a global UNI.
+     *
+     * @param uni the service UNI to be added
+     */
+    public void addServiceUni(CarrierEthernetUni uni) {
+
+        // Add CE-VLAN ID
+        if (uni.ceVlanId() != null) {
+            this.ceVlanIdSet.add(uni.ceVlanId());
+        }
+
+        // Add UNI BWP
+        CarrierEthernetBandwidthProfile bwp = uni.bwp();
+        Map<String, CarrierEthernetBandwidthProfile> subBwpMap = this.bwpMap.get(bwp.type());
+        subBwpMap.put(bwp.id(), bwp);
+        this.bwpMap.put(bwp.type(), subBwpMap);
+        // Used capacity cannot be more than UNI capacity (redundant check - should be avoided by check in validateBwp)
+        this.usedCapacity = Bandwidth.bps(Math.min(this.usedCapacity.bps() + bwp.cir().bps(), this.capacity.bps()));
+    }
+
+    /**
+     * Adds a BW profile to a UNI.
+     *
+     * @param bwp the BWP to be added
+     */
+    public void addBandwidthProfile(CarrierEthernetBandwidthProfile bwp) {
+
+        Map<String, CarrierEthernetBandwidthProfile> subBwpMap = this.bwpMap.get(bwp.type());
+        subBwpMap.put(bwp.id(), bwp);
+        this.bwpMap.put(bwp.type(), subBwpMap);
+        // Used capacity cannot be more than UNI capacity (redundant check - should be avoided by check in validateBwp)
+        this.usedCapacity = Bandwidth.bps(Math.min(this.usedCapacity.bps() + bwp.cir().bps(), this.capacity.bps()));
+    }
+
+    /**
+     * Removes the resources associated with a service-specific UNI from a global UNI.
+     *
+     * @param uni the service UNI to be added
+     */
+    public void removeServiceUni(CarrierEthernetUni uni) {
+
+        // Remove UNI CE-VLAN ID
+        ceVlanIdSet.remove(uni.ceVlanId());
+
+        // Remove UNI BWP
+        CarrierEthernetBandwidthProfile bwp = uni.bwp();
+        Map<String, CarrierEthernetBandwidthProfile> subBwpMap = this.bwpMap.get(bwp.type());
+        subBwpMap.remove(bwp.id());
+        this.bwpMap.put(bwp.type(), subBwpMap);
+        // Redundant check - should be avoided by check in validateBwp
+        this.usedCapacity = Bandwidth.bps(Math.max(this.usedCapacity.bps() - bwp.cir().bps(), 0));
+    }
+
+    /**
+     * Validates whether a service-specific UNI is compatible with a global UNI.
+     *
+     * @param uni the service-specific UNI
+     * @return boolean value indicating whether the UNIs are compatible
+     */
+    public boolean validateServiceUni(CarrierEthernetUni uni) {
+
+        // Check if the CE-VLAN ID of the UNI is already included in global UNI
+        if (uni.ceVlanId() != null) {
+            if (ceVlanIdSet.contains(uni.ceVlanId())) {
+                log.error("CE-VLAN ID {} already exists in UNI {}", uni.ceVlanId().toString(), this.id());
+                return false;
+            }
+        }
+
+        CarrierEthernetBandwidthProfile bwp = uni.bwp();
+
+        // Check if the UNI BW profile is allowed based on its type and id and the existing profiles on the global UNI
+        for (CarrierEthernetBandwidthProfile.Type bwpType : CarrierEthernetBandwidthProfile.Type.values()) {
+            Map<String, CarrierEthernetBandwidthProfile> subBwpMap = this.bwpMap.get(bwpType);
+            if (!(subBwpMap.isEmpty())) {
+                if (bwpType != bwp.type()) {
+                    log.error("Different bandwidth profile type than {} already exists in UNI {}",
+                            bwp.type().name(), this.id());
+                    return false;
+                } else if (subBwpMap.containsKey(bwp.id())) {
+                    log.error("Bandwidth profile {} already exists in UNI {}", bwp.id(), this.id());
+                    return false;
+                } else if (bwp.type().equals(CarrierEthernetBandwidthProfile.Type.INTERFACE)) {
+                    log.error("Another bandwidth profile already exists in UNI {}", this.id());
+                    return false;
+                }
+            }
+        }
+
+        // Check whether there are enough available resources on the UNI
+        if (usedCapacity.bps() + bwp.cir().bps() > capacity.bps()) {
+            log.error("Bandwidth profile {} cannot be added to UNI {} due to lack of resources", bwp.id(), this.id());
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Returns associated connect point.
+     *
+     * @return associated connect point
+     */
+    public ConnectPoint cp() {
+        return connectPoint;
+    }
+
+    /**
+     * Returns UNI string identifier.
+     *
+     * @return UNI string identifier
+     */
+    public String id() {
+        return uniId;
+    }
+
+    /**
+     * Returns UNI string config identifier.
+     *
+     * @return UNI string config identifier
+     */
+    public String cfgId() {
+        return uniCfgId;
+    }
+
+    /**
+     * Returns UNI type (ROOT or LEAF) - applicable only to service-specific UNIs.
+     *
+     * @return UNI type
+     */
+    public Type type() {
+        return type;
+    }
+
+    /**
+     * Returns the CE-VLAN id associated with a local UNI, or the first CE-VLAN ID found for a global UNI.
+     *
+     * @return CE-VLAN id
+     */
+    public VlanId ceVlanId() {
+        if (ceVlanIdSet.isEmpty()) {
+            return null;
+        } else {
+            return ceVlanIdSet.iterator().next();
+        }
+    }
+
+    /**
+     * Returns the set of CE-VLAN ids associated with the UNI.
+     *
+     * @return CE-VLAN id set
+     */
+    public Set<VlanId> ceVlanIdSet() {
+        return ceVlanIdSet;
+    }
+
+    /**
+     * Returns the first non-null BWP of the UNI found - used mainly for service-specific UNIs.
+     * Note: The Service-specific UNI representation will only have one BWP
+     *
+     * @return first non-null BWP of the UNI
+     */
+    public CarrierEthernetBandwidthProfile bwp() {
+
+        for (CarrierEthernetBandwidthProfile.Type bwpType : CarrierEthernetBandwidthProfile.Type.values()) {
+            if (!(this.bwpMap.get(bwpType).isEmpty())) {
+                return bwpMap.get(bwpType).entrySet().iterator().next().getValue();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns a collection of all BWPs of the UNI
+     *
+     * @return all BWPs of the UNI
+     */
+    public Collection<CarrierEthernetBandwidthProfile> bwps() {
+
+        for (CarrierEthernetBandwidthProfile.Type bwpType : CarrierEthernetBandwidthProfile.Type.values()) {
+            if (!(this.bwpMap.get(bwpType).isEmpty())) {
+                return bwpMap.get(bwpType).values();
+            }
+        }
+        // Return an empty collection if no BWPs exist
+        return Collections.emptyList();
+    }
+
+    /**
+     * Returns UNI capacity in bps.
+     *
+     * @return UNI capacity
+     */
+    public Bandwidth capacity() {
+        return capacity;
+    }
+
+    /**
+     * Sets UNI string identifier.
+     *
+     * @param uniId the UNI string identifier to set
+     */
+    public void setId(String uniId) {
+        this.uniId = uniId;
+    }
+
+    /**
+     * Sets UNI string config identifier.
+     *
+     * @param uniCfgId the UNI string config identifier to set
+     */
+    public void setCfgId(String uniCfgId) {
+        this.uniCfgId = uniCfgId;
+    }
+
+    @Override
+    public String toString() {
+
+        return toStringHelper(this)
+                .add("id", uniId)
+                .add("cfgId", uniCfgId)
+                .add("type", type)
+                .add("ceVlanIds", ceVlanIdSet)
+                .add("capacity", capacity)
+                .add("usedCapacity", usedCapacity)
+                .add("bandwidthProfiles", this.bwps()).toString();
+    }
+
+}
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/package-info.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/package-info.java
new file mode 100644
index 0000000..4b5dc67
--- /dev/null
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/**
+ * Implementation of carrier ethernet service generation.
+ */
+package org.onosproject.ecord.carrierethernet.app;
\ No newline at end of file
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetCreateServiceCommand.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetCreateServiceCommand.java
new file mode 100644
index 0000000..ae2d2cc
--- /dev/null
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetCreateServiceCommand.java
@@ -0,0 +1,172 @@
+/*
+ * 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.ecord.carrierethernet.cli;
+
+import com.google.common.collect.Lists;
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+import org.onlab.packet.VlanId;
+import org.onlab.util.Bandwidth;
+import org.onosproject.ecord.carrierethernet.app.CarrierEthernetBandwidthProfile;
+import org.onosproject.ecord.carrierethernet.app.CarrierEthernetManager;
+import org.onosproject.ecord.carrierethernet.app.CarrierEthernetService;
+import org.onosproject.ecord.carrierethernet.app.CarrierEthernetUni;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.ConnectPoint;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * CLI command for generating CE services.
+ */
+@Command(scope = "onos", name = "ce-service-create",
+         description = "Carrier Ethernet service creation command.")
+public class CarrierEthernetCreateServiceCommand extends AbstractShellCommand {
+
+    @Argument(index = 0, name = "argServiceCfgId",
+            description = "Service configuration ID", required = true, multiValued = false)
+    String argServiceCfgId = null;
+    @Argument(index = 1, name = "argServiceType", description =
+            "Service type (defaults to POINT_TO_POINT or MULTIPOINT_TO_MULTIPOINT, depending on number of UNIs)",
+            required = false, multiValued = false)
+    String argServiceType = null;
+    @Argument(index = 2, name = "argFirstUni", description =
+            "First UNI in list (if point to multipoint, this is the root)", required = true, multiValued = false)
+    String argFirstUni = null;
+    @Argument(index = 3, name = "argUniList",
+            description = "List of remaining UNIs (if point to multipoint, these are the leaves)",
+            required = true, multiValued = true)
+    List<String> argUniList = Lists.newArrayList();
+    @Option(name = "-v", aliases = "--cevlan", description = "CE-VLAN ID (applied to all UNIs)",
+            required = false, multiValued = false)
+    String argCeVlanId = null;
+    @Option(name = "-id", aliases = "--service-id", description = "The ID of a service to be updated" +
+            " (if service does not exist, a new service will be installed)", required = false, multiValued = false)
+    String argServiceId = null;
+    @Option(name = "-c", aliases = "--cir", description = "The CIR in Mbps", required = false, multiValued = false)
+    String argCir = "0";
+    @Option(name = "-e", aliases = "--eir", description = "The EIR in Mbps", required = false, multiValued = false)
+    String argEir = "0";
+    @Option(name = "-cbs", aliases = "--cbs", description = "The CBS in Bytes", required = false, multiValued = false)
+    String argCbs = "0";
+    @Option(name = "-ebs", aliases = "--ebs", description = "The EBS in Bytes", required = false, multiValued = false)
+    String argEbs = "0";
+
+    // TODO: Add further arguments for VLAN tag preservation, CoS preservation etc.
+
+    @Override
+    protected void execute() {
+
+        CarrierEthernetManager cem = get(CarrierEthernetManager.class);
+
+        CarrierEthernetService service = new CarrierEthernetService(argServiceId, argServiceCfgId,
+                generateServiceType(), generateUniSet());
+
+        cem.establishConnectivity(service);
+    }
+
+    /**
+     * Return the CE-VLAN ID for the CE service based on the CLI-supplied argument.
+     *
+     * @return CE-VLAN ID for the CE service
+     */
+    VlanId generateCeVlanId() {
+        return ((argCeVlanId == null) ? null : VlanId.vlanId(Short.parseShort(argCeVlanId)));
+    }
+
+    /**
+     * Return the CE service type based on the CLI-supplied arguments.
+     *
+     * @return the CE service type
+     */
+    CarrierEthernetService.Type generateServiceType() {
+        if (argServiceType == null) {
+            return ((argUniList.size() > 2) ?
+                    CarrierEthernetService.Type.MULTIPOINT_TO_MULTIPOINT : CarrierEthernetService.Type.POINT_TO_POINT);
+        } else {
+            return CarrierEthernetService.Type.valueOf(argServiceType);
+        }
+    }
+
+    /**
+     * Return the BW profile type based on the CLI-supplied arguments.
+     *
+     * @return the BWP profile type
+     */
+    CarrierEthernetBandwidthProfile.Type generateBandwidthProfileType() {
+        // TODO: Add the CoS BW profile case
+        return ((argCeVlanId == null) ?
+                CarrierEthernetBandwidthProfile.Type.INTERFACE : CarrierEthernetBandwidthProfile.Type.EVC);
+    }
+
+    /**
+     * Return the BW profile id based on the CLI-supplied arguments.
+     *
+     * @param uniId the UNI id
+     * @return the BW profile id
+     */
+    String generateBandwidthProfileId(String uniId) {
+        // TODO: Add the CoS BW profile case
+        return ((argCeVlanId == null) ? uniId : argServiceCfgId);
+    }
+
+    /**
+     * Return the set of UNIs for the CE service based on the CLI-supplied arguments.
+     *
+     * @return the set of UNIs for the CE service
+     */
+    Set<CarrierEthernetUni> generateUniSet() {
+
+        Set<CarrierEthernetUni> uniSet = new HashSet<>();
+
+        CarrierEthernetService.Type serviceType = generateServiceType();
+
+        // We assume that first UNI supplied is always root
+        uniSet.add(new CarrierEthernetUni(ConnectPoint.deviceConnectPoint(argFirstUni), null,
+                CarrierEthernetUni.Type.ROOT, generateCeVlanId(),
+                new CarrierEthernetBandwidthProfile(
+                        generateBandwidthProfileId(argFirstUni),
+                        null,
+                        generateBandwidthProfileType(),
+                        Bandwidth.mbps(Double.parseDouble(argCir)),
+                        Bandwidth.mbps(Double.parseDouble(argEir)),
+                        Long.parseLong(argCbs),
+                        Long.parseLong(argEbs)
+                )));
+
+        final CarrierEthernetUni.Type uniType;
+        // For E-Line and E-LAN all UNIs are roots. For E-Tree all UNIs are leafs except from one
+        uniType = ((serviceType == CarrierEthernetService.Type.ROOT_MULTIPOINT) ?
+                CarrierEthernetUni.Type.LEAF : CarrierEthernetUni.Type.ROOT);
+
+        argUniList.forEach(argUni -> uniSet.add(new CarrierEthernetUni(ConnectPoint.deviceConnectPoint(argUni), null,
+                uniType, generateCeVlanId(),
+                new CarrierEthernetBandwidthProfile(
+                        generateBandwidthProfileId(argUni),
+                        null,
+                        generateBandwidthProfileType(),
+                        Bandwidth.mbps(Double.parseDouble(argCir)),
+                        Bandwidth.mbps(Double.parseDouble(argEir)),
+                        Long.parseLong(argCbs),
+                        Long.parseLong(argEbs)
+                ))));
+
+        return uniSet;
+    }
+}
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetListServicesCommand.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetListServicesCommand.java
new file mode 100644
index 0000000..ee1dbc1
--- /dev/null
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetListServicesCommand.java
@@ -0,0 +1,41 @@
+/*
+ * 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.ecord.carrierethernet.cli;
+
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.ecord.carrierethernet.app.CarrierEthernetManager;
+import org.onosproject.ecord.carrierethernet.app.CarrierEthernetService;
+import org.onosproject.cli.AbstractShellCommand;
+
+import java.util.Collection;
+
+/**
+ * CLI command for listing all installed CE services.
+ */
+@Command(scope = "onos", name = "ce-service-list",
+        description = "Lists all Carrier Ethernet services.")
+public class CarrierEthernetListServicesCommand extends AbstractShellCommand {
+
+    @Override
+    protected void execute() {
+        CarrierEthernetManager cem = get(CarrierEthernetManager.class);
+        printServices(cem.serviceMap().values());
+    }
+
+    private void printServices(Collection<CarrierEthernetService> services) {
+        services.forEach(service -> print("  %s", service));
+    }
+}
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetListUnisCommand.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetListUnisCommand.java
new file mode 100644
index 0000000..71ca648
--- /dev/null
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetListUnisCommand.java
@@ -0,0 +1,43 @@
+/*
+ * 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.ecord.carrierethernet.cli;
+
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.ecord.carrierethernet.app.CarrierEthernetManager;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.ecord.carrierethernet.app.CarrierEthernetUni;
+
+import java.util.Collection;
+
+/**
+ * CLI command for listing all CE UNIs.
+ */
+@Command(scope = "onos", name = "ce-uni-list",
+        description = "Lists all Carrier Ethernet UNIs.")
+public class CarrierEthernetListUnisCommand extends AbstractShellCommand {
+
+    @Override
+    protected void execute() {
+        CarrierEthernetManager cem = get(CarrierEthernetManager.class);
+        // Populate global UNI map
+        cem.addGlobalUnis();
+        printUnis(cem.getUniMap().values());
+    }
+
+    private void printUnis(Collection<CarrierEthernetUni> unis) {
+        unis.forEach(uni -> print("  %s", uni));
+    }
+}
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetRemoveAllServicesCommand.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetRemoveAllServicesCommand.java
new file mode 100644
index 0000000..0232e82
--- /dev/null
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetRemoveAllServicesCommand.java
@@ -0,0 +1,34 @@
+/*
+ * 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.ecord.carrierethernet.cli;
+
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.ecord.carrierethernet.app.CarrierEthernetManager;
+import org.onosproject.cli.AbstractShellCommand;
+
+/**
+ * CLI command for removing all installed CE services.
+ */
+@Command(scope = "onos", name = "ce-service-remove-all",
+        description = "Carrier Ethernet all services removal.")
+public class CarrierEthernetRemoveAllServicesCommand extends AbstractShellCommand {
+
+    @Override
+    protected void execute() {
+        CarrierEthernetManager cem = get(CarrierEthernetManager.class);
+        cem.removeAllServices();
+    }
+}
\ No newline at end of file
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetRemoveServiceCommand.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetRemoveServiceCommand.java
new file mode 100644
index 0000000..1c088cb
--- /dev/null
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetRemoveServiceCommand.java
@@ -0,0 +1,38 @@
+/*
+ * 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.ecord.carrierethernet.cli;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.ecord.carrierethernet.app.CarrierEthernetManager;
+import org.onosproject.cli.AbstractShellCommand;
+
+/**
+ * CLI command for removing a specific installed CE service.
+ */
+@Command(scope = "onos", name = "ce-service-remove",
+        description = "Carrier Ethernet service removal command.")
+public class CarrierEthernetRemoveServiceCommand extends AbstractShellCommand {
+
+    @Argument(index = 0, name = "argServiceId", description = "Service ID", required = true, multiValued = false)
+    String argServiceId = null;
+
+    @Override
+    protected void execute() {
+        CarrierEthernetManager cem = get(CarrierEthernetManager.class);
+        cem.removeService(argServiceId);
+    }
+}
\ No newline at end of file
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetServiceIdCompleter.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetServiceIdCompleter.java
new file mode 100644
index 0000000..7ebc192
--- /dev/null
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetServiceIdCompleter.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2015 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.ecord.carrierethernet.cli;
+
+import org.apache.karaf.shell.console.Completer;
+import org.apache.karaf.shell.console.completer.StringsCompleter;
+import org.onosproject.ecord.carrierethernet.app.CarrierEthernetManager;
+import org.onosproject.cli.AbstractShellCommand;
+
+import java.util.List;
+import java.util.SortedSet;
+
+public class CarrierEthernetServiceIdCompleter implements Completer {
+    @Override
+    public int complete(String buffer, int cursor, List<String> candidates) {
+
+        StringsCompleter delegate = new StringsCompleter();
+        CarrierEthernetManager cem = AbstractShellCommand.get(CarrierEthernetManager.class);
+        SortedSet<String> strings = delegate.getStrings();
+        cem.serviceMap().keySet().forEach(serviceId -> strings.add(serviceId));
+        return delegate.complete(buffer, cursor, candidates);
+    }
+}
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetServiceTypeCompleter.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetServiceTypeCompleter.java
new file mode 100644
index 0000000..0499cf8
--- /dev/null
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetServiceTypeCompleter.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2015 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.ecord.carrierethernet.cli;
+
+import org.apache.karaf.shell.console.Completer;
+import org.apache.karaf.shell.console.completer.StringsCompleter;
+
+import java.util.List;
+import java.util.SortedSet;
+
+public class CarrierEthernetServiceTypeCompleter implements Completer {
+    @Override
+    public int complete(String buffer, int cursor, List<String> candidates) {
+
+        StringsCompleter delegate = new StringsCompleter();
+
+        SortedSet<String> strings = delegate.getStrings();
+
+        strings.add("POINT_TO_POINT");
+        strings.add("MULTIPOINT_TO_MULTIPOINT");
+        strings.add("ROOT_MULTIPOINT");
+
+        return delegate.complete(buffer, cursor, candidates);
+    }
+
+}
+
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetUniCompleter.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetUniCompleter.java
new file mode 100644
index 0000000..f8d6f03
--- /dev/null
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetUniCompleter.java
@@ -0,0 +1,65 @@
+/*
+ * 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.ecord.carrierethernet.cli;
+
+import org.apache.karaf.shell.console.Completer;
+import org.apache.karaf.shell.console.completer.StringsCompleter;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Device;
+import org.onosproject.net.Port;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.link.LinkService;
+
+import java.util.List;
+import java.util.SortedSet;
+
+/**
+ * UNI ConnectPoint completer.
+ */
+public class CarrierEthernetUniCompleter implements Completer {
+    @Override
+    public int complete(String buffer, int cursor, List<String> candidates) {
+
+        // TODO: Add memory
+
+        StringsCompleter delegate = new StringsCompleter();
+
+        LinkService linkService = AbstractShellCommand.get(LinkService.class);
+        DeviceService service = AbstractShellCommand.get(DeviceService.class);
+
+        // Generate the device ID/port number identifiers
+        for (Device device : service.getDevices()) {
+            SortedSet<String> strings = delegate.getStrings();
+            for (Port port : service.getPorts(device.id())) {
+                // Consider only physical ports which are currently active
+                if (!port.number().isLogical() && port.isEnabled()) {
+                    String cpString = device.id().toString() + "/" + port.number();
+                    ConnectPoint cp = ConnectPoint.deviceConnectPoint(cpString);
+                    // Add the generated connect point only if it doesn't belong to any link
+                    // and if the device is a packet switch
+                    if (linkService.getEgressLinks(cp).isEmpty() && linkService.getIngressLinks(cp).isEmpty() &&
+                            device.type().equals(Device.Type.SWITCH)) {
+                        strings.add(cpString);
+                    }
+                }
+            }
+        }
+
+        return delegate.complete(buffer, cursor, candidates);
+    }
+
+}
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/package-info.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/package-info.java
new file mode 100644
index 0000000..32e8e79
--- /dev/null
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/**
+ * CLI implementation for requesting carrier ethernet services.
+ */
+package org.onosproject.ecord.carrierethernet.cli;
\ No newline at end of file
diff --git a/ecord/carrierethernet/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/ecord/carrierethernet/src/main/resources/OSGI-INF/blueprint/shell-config.xml
new file mode 100644
index 0000000..886a712
--- /dev/null
+++ b/ecord/carrierethernet/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -0,0 +1,63 @@
+<!--
+  ~ 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.
+  -->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+
+    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
+        <command>
+            <action class="org.onosproject.ecord.carrierethernet.cli.CarrierEthernetCreateServiceCommand"/>
+            <completers>
+                <ref component-id="placeholderCompleter"/>
+                <ref component-id="carrierEthernetServiceTypeCompleter"/>
+                <ref component-id="carrierEthernetUniCompleter"/>
+                <ref component-id="carrierEthernetUniCompleter"/>
+            </completers>
+        </command>
+    </command-bundle>
+
+    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
+        <command>
+            <action class="org.onosproject.ecord.carrierethernet.cli.CarrierEthernetRemoveServiceCommand"/>
+            <completers>
+                <ref component-id="carrierEthernetServiceIdCompleter"/>
+            </completers>
+        </command>
+    </command-bundle>
+
+    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
+        <command>
+            <action class="org.onosproject.ecord.carrierethernet.cli.CarrierEthernetRemoveAllServicesCommand"/>
+        </command>
+    </command-bundle>
+
+    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
+        <command>
+            <action class="org.onosproject.ecord.carrierethernet.cli.CarrierEthernetListServicesCommand"/>
+        </command>
+    </command-bundle>
+
+    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
+        <command>
+            <action class="org.onosproject.ecord.carrierethernet.cli.CarrierEthernetListUnisCommand"/>
+        </command>
+    </command-bundle>
+
+    <bean id="placeholderCompleter" class="org.onosproject.cli.PlaceholderCompleter"/>
+    <bean id="carrierEthernetServiceTypeCompleter" class="org.onosproject.ecord.carrierethernet.cli.CarrierEthernetServiceTypeCompleter"/>
+    <bean id="carrierEthernetServiceIdCompleter" class="org.onosproject.ecord.carrierethernet.cli.CarrierEthernetServiceIdCompleter"/>
+    <bean id="carrierEthernetUniCompleter" class="org.onosproject.ecord.carrierethernet.cli.CarrierEthernetUniCompleter"/>
+    <bean id="connectPointCompleter" class="org.onosproject.cli.net.ConnectPointCompleter"/>
+
+</blueprint>
