diff --git a/local/ce-vee/pom.xml b/local/ce-vee/pom.xml
new file mode 100644
index 0000000..5ac2ee6
--- /dev/null
+++ b/local/ce-vee/pom.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2017-present Open Networking Foundation
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<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>
+
+    <parent>
+        <groupId>org.opencord.ce</groupId>
+        <artifactId>local</artifactId>
+        <version>1.0.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>vee</artifactId>
+    <packaging>bundle</packaging>
+    <version>1.0.0-SNAPSHOT</version>
+
+    <description>Virtual Ethernet Edge service for CORD</description>
+
+    <properties>
+        <onos.app.name>org.opencord.ce.local.vee</onos.app.name>
+        <onos.app.title>E-CORD Ethernet Edge app</onos.app.title>
+        <onos.app.url>http://opencord.org</onos.app.url>
+        <onos.app.requires>org.opencord.ce.local.bigswitch</onos.app.requires>
+        <onos.app.requires>org.opencord.ce.local.channel.http</onos.app.requires>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.opencord.ce</groupId>
+            <artifactId>bigswitch</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-scr-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.onosproject</groupId>
+                <artifactId>onos-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+
+    <repositories>
+        <repository>
+            <id>snapshots</id>
+            <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+            <releases><enabled>false</enabled></releases>
+        </repository>
+    </repositories>
+
+    <pluginRepositories>
+        <pluginRepository>
+            <id>snapshots</id>
+            <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+            <releases><enabled>false</enabled></releases>
+        </pluginRepository>
+    </pluginRepositories>
+
+</project>
diff --git a/local/ce-vee/src/main/java/org/opencord/ce/local/vee/VeeManager.java b/local/ce-vee/src/main/java/org/opencord/ce/local/vee/VeeManager.java
new file mode 100644
index 0000000..1ac2b21
--- /dev/null
+++ b/local/ce-vee/src/main/java/org/opencord/ce/local/vee/VeeManager.java
@@ -0,0 +1,730 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opencord.ce.local.vee;
+
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.packet.EthType;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.VlanId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.Path;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.driver.Driver;
+import org.onosproject.net.driver.DriverService;
+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.instructions.Instruction;
+import org.onosproject.net.flow.instructions.Instructions;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction;
+import org.onosproject.net.flowobjective.DefaultFilteringObjective;
+import org.onosproject.net.flowobjective.DefaultForwardingObjective;
+import org.onosproject.net.flowobjective.DefaultNextObjective;
+import org.onosproject.net.flowobjective.FilteringObjective;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.NextObjective;
+import org.onosproject.net.flowobjective.Objective;
+import org.onosproject.net.link.LinkService;
+import org.onosproject.net.meter.Band;
+import org.onosproject.net.meter.DefaultBand;
+import org.onosproject.net.meter.DefaultMeterRequest;
+import org.onosproject.net.meter.Meter;
+import org.onosproject.net.meter.MeterId;
+import org.onosproject.net.meter.MeterRequest;
+import org.onosproject.net.meter.MeterService;
+import org.onosproject.net.topology.PathService;
+import org.opencord.ce.api.models.CarrierEthernetEnni;
+import org.opencord.ce.api.models.CarrierEthernetForwardingConstruct;
+import org.opencord.ce.api.models.CarrierEthernetGenericNi;
+import org.opencord.ce.api.models.CarrierEthernetInni;
+import org.opencord.ce.api.models.CarrierEthernetNetworkInterface;
+import org.opencord.ce.api.models.CarrierEthernetUni;
+import org.opencord.ce.api.models.EvcConnId;
+import org.opencord.ce.api.services.MetroNetworkVirtualNodeService;
+
+import org.opencord.ce.local.bigswitch.BigSwitchService;
+import org.slf4j.Logger;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
+
+import static org.slf4j.LoggerFactory.getLogger;
+import static org.opencord.ce.api.models.CarrierEthernetNetworkInterface.Type;
+import static org.onosproject.net.DefaultEdgeLink.createEdgeLink;
+
+/**
+ * Class used to control Ethernet Edge nodes according to the OpenFlow (1.3 and above) protocol.
+ */
+@Component(immediate = true)
+@Service(value = MetroNetworkVirtualNodeService.class)
+public class VeeManager implements MetroNetworkVirtualNodeService {
+    private static final int PRIORITY = 50000;
+    public static final String APP_NAME = "org.opencord.ce.local.vee";
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected FlowRuleService flowRuleService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected MeterService meterService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected FlowObjectiveService flowObjectiveService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected LinkService linkService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected BigSwitchService bigSwitchService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected PathService pathService;
+
+    // FIXME slightly better way to detect OF-DPA issues
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DriverService drivers;
+
+    private final Logger log = getLogger(getClass());
+
+    private ApplicationId appId;
+
+    // FIXME: We don't need to store the submitted meters as we can get them from the service
+    private Map<EvcConnId, Set<Pair<DeviceId, MeterId>>> fcMeterMap =
+            new ConcurrentHashMap<>();
+    // Store submitted flow objects as the service does not allow query operations
+    private final Map<EvcConnId, LinkedList<Pair<DeviceId, Objective>>> flowObjectiveMap =
+            new ConcurrentHashMap<>();
+
+    private final Map<EvcConnId, DeviceId> eeDeviceMap = new ConcurrentHashMap<>();
+
+    @Activate
+    protected void activate() {
+        appId = coreService.registerApplication(APP_NAME);
+
+        // TODO: start packet intercept for untagged traffic?
+        log.info("Started");
+
+       // testCentec();
+    }
+
+    @Deactivate
+    protected void deactivate() {
+
+        log.info("Stopped");
+    }
+
+
+    @Override
+    public void setNodeForwarding(CarrierEthernetForwardingConstruct fc, CarrierEthernetNetworkInterface ingressNi,
+                                  Set<CarrierEthernetNetworkInterface> egressNiSet) {
+
+        log.info("DEBUG: setForwarding method called..");
+        if (ingressNi == null || egressNiSet.isEmpty()) {
+            log.error("There needs to be at least one ingress and one egress NI to set forwarding.");
+            return;
+        }
+
+        flowObjectiveMap.putIfAbsent(fc.id(), new LinkedList<>());
+
+        CarrierEthernetNetworkInterface realIngressNi;
+        Optional<ConnectPoint> optCp =
+                bigSwitchService.connectPointFromVirtPort(ingressNi.cp().port());
+        if (optCp.isPresent()) {
+            realIngressNi = buildLocalNi(optCp.get(), ingressNi);
+        } else {
+            log.warn("Virtual ingress interface does not map to a local connect point");
+            return;
+        }
+
+        // real <-> virtual
+        final Map<ConnectPoint, CarrierEthernetNetworkInterface> realEgressNi = new HashMap<>();
+        egressNiSet.forEach(egressNi -> {
+            Optional<ConnectPoint> opt =
+                    bigSwitchService.connectPointFromVirtPort(egressNi.cp().port());
+            opt.ifPresent(connectPoint -> realEgressNi.put(connectPoint, egressNi));
+        });
+
+        // it is necessary to identify the number of egress devices in order to build the
+        // flow rules
+        Set<DeviceId> egressDevices = new HashSet<>();
+        realEgressNi.keySet().forEach(cp -> egressDevices.add(cp.deviceId()));
+
+        //for how it is made the CE app, egressNiSet contains only one item, but...
+        egressDevices.forEach(deviceId -> {
+            // group the egress NI per device
+            Set<CarrierEthernetNetworkInterface> perDeviceEgressNiSet = new HashSet<>();
+            realEgressNi.keySet().forEach(cp -> {
+                if (cp.deviceId().equals(deviceId)) {
+                    perDeviceEgressNiSet.add(buildLocalNi(cp, realEgressNi.get(cp)));
+                }
+            });
+            // if the egress device ID is equal to the ingress --> install rules
+            if (deviceId.equals(realIngressNi.cp().deviceId())) {
+                createFlowObjectives(fc, realIngressNi,
+                        perDeviceEgressNiSet);
+            } else {
+                Set<Path> paths = pathService.getPaths(realIngressNi.cp().deviceId(),
+                        deviceId);
+                Path path;
+                // TODO: Select path in more sophisticated way and return null if any of the constraints cannot be met
+                path = paths.iterator().hasNext() ? paths.iterator().next() : null;
+                if (path == null) {
+                    return;
+                }
+                // for each NI, add edge links ()
+                perDeviceEgressNiSet.forEach(egressNi -> {
+                    List<Link> links = new ArrayList<>();
+                    links.add(createEdgeLink(realIngressNi.cp(), true));
+                    links.addAll(path.links());
+                    links.add(createEdgeLink(egressNi.cp(), false));
+
+                    HashMap<CarrierEthernetNetworkInterface, HashSet<CarrierEthernetNetworkInterface>>
+                            ingressEgressNiMap = new HashMap<>();
+                    populateIngressEgressNiMap(realIngressNi, egressNi, links, ingressEgressNiMap);
+                    // Establish connectivity using the ingressEgressNiMap
+                    ingressEgressNiMap.keySet().forEach(srcNi ->
+                        createFlowObjectives(fc, srcNi, ingressEgressNiMap.get(srcNi)));
+                });
+            }
+        });
+    }
+
+    private void populateIngressEgressNiMap(CarrierEthernetNetworkInterface srcNi,
+                                            CarrierEthernetNetworkInterface dstNi,
+                                            List<Link> linkList,
+                                            HashMap<CarrierEthernetNetworkInterface,
+                                                    HashSet<CarrierEthernetNetworkInterface>> ingressEgressNiMap
+    ) {
+        // FIXME: Fix the method - avoid generating GENERIC NIs if not needed
+        // Add the src and destination NIs as well as the associated Generic NIs
+        ingressEgressNiMap.putIfAbsent(srcNi, new HashSet<>());
+        // Add last hop entry only if srcNi, dstNi aren't on same device (in which case srcNi, ingressNi would coincide)
+        if (!srcNi.cp().deviceId().equals(dstNi.cp().deviceId())) {
+            // If srcNi, dstNi are not on the same device, create mappings to/from new GENERIC NIs
+            ingressEgressNiMap.get(srcNi).add(new CarrierEthernetGenericNi(linkList.get(1).src(), null));
+            CarrierEthernetGenericNi ingressNi =
+                    new CarrierEthernetGenericNi(linkList.get(linkList.size() - 2).dst(), null);
+            ingressEgressNiMap.putIfAbsent(ingressNi, new HashSet<>());
+            ingressEgressNiMap.get(ingressNi).add(dstNi);
+        } else {
+            // If srcNi, dstNi are on the same device, this is the only mapping that will be created
+            ingressEgressNiMap.get(srcNi).add(dstNi);
+        }
+
+        // Go through the links and create/add the intermediate NIs
+        for (int i = 1; i < linkList.size() - 2; i++) {
+            CarrierEthernetGenericNi ingressNi = new CarrierEthernetGenericNi(linkList.get(i).dst(), null);
+            ingressEgressNiMap.putIfAbsent(ingressNi, new HashSet<>());
+            ingressEgressNiMap.get(ingressNi).add(new CarrierEthernetGenericNi(linkList.get(i + 1).src(), null));
+        }
+    }
+
+    private CarrierEthernetNetworkInterface buildLocalNi(ConnectPoint localCp, CarrierEthernetNetworkInterface
+                                                         virtualNi) {
+        CarrierEthernetNetworkInterface ni;
+        switch (virtualNi.type()) {
+            case UNI:
+                CarrierEthernetUni tmpUni = (CarrierEthernetUni) virtualNi;
+                ni = CarrierEthernetUni.builder()
+                        .cp(localCp)
+                        .role(tmpUni.role())
+                        .ceVlanId(tmpUni.ceVlanId())
+                        .bwp(tmpUni.bwp())
+                        .build();
+                break;
+            case ENNI:
+                CarrierEthernetEnni tmpEnni = (CarrierEthernetEnni) virtualNi;
+                ni = CarrierEthernetEnni.builder()
+                        .cp(localCp)
+                        .role(tmpEnni.role())
+                        .sVlanId(tmpEnni.sVlanId())
+                        .build();
+                break;
+            case INNI:
+                CarrierEthernetInni tmpInni = (CarrierEthernetInni) virtualNi;
+                ni = CarrierEthernetInni.builder()
+                        .cp(localCp)
+                        .role(tmpInni.role())
+                        .sVlanId(tmpInni.sVlanId())
+                        .build();
+                break;
+            case GENERIC:
+                ni = new CarrierEthernetGenericNi(localCp, null);
+                break;
+            default:
+                return null;
+        }
+        return ni;
+
+    }
+
+    /**
+     * Creates and submits FlowObjectives into the device vesting the role of Ethernet Edge.
+     *
+     * @param fc the FC representation
+     * @param ingressNi the ingress network interface
+     * @param  egressNiSet the set of egress NIs
+     */
+    private void createFlowObjectives(CarrierEthernetForwardingConstruct fc, CarrierEthernetNetworkInterface ingressNi,
+                                      Set<CarrierEthernetNetworkInterface> egressNiSet) {
+        DeviceId deviceId = ingressNi.cp().deviceId();
+        PortNumber portNumber = ingressNi.cp().port();
+
+        /////////////////////////////////////////
+        // Prepare and submit filtering objective
+        /////////////////////////////////////////
+
+        FilteringObjective.Builder filterObjBuilder = DefaultFilteringObjective.builder()
+                .permit().fromApp(appId)
+                .withPriority(PRIORITY)
+                .withKey(Criteria.matchInPort(portNumber));
+
+        TrafficTreatment.Builder filterTreatmentBuilder = DefaultTrafficTreatment.builder();
+        // In general, nodes would match on the VLAN tag assigned to the EVC/FC
+        Criterion filterVlanIdCriterion = Criteria.matchVlanId(fc.vlanId());
+
+        if ((ingressNi.type().equals(CarrierEthernetNetworkInterface.Type.INNI))
+                || (ingressNi.type().equals(CarrierEthernetNetworkInterface.Type.ENNI))) {
+            // TODO: Check TPID? Also: Is is possible to receive untagged pkts at an INNI/ENNI?
+            // Source node of an FC should match on S-TAG if it's an INNI/ENNI
+            filterVlanIdCriterion = Criteria.matchVlanId(ingressNi.sVlanId());
+            // Translate S-TAG to the one used in the current FC
+            filterTreatmentBuilder.setVlanId(fc.vlanId());
+        } else if (ingressNi.type().equals(CarrierEthernetNetworkInterface.Type.UNI)) {
+            // Source node of an FC should match on CE-VLAN ID (if present) if it's a UNI
+            filterVlanIdCriterion = Criteria.matchVlanId(ingressNi.ceVlanId());
+            // Obtain related Meter (if it exists) and add it in the treatment in case it may be used
+            if (fcMeterMap.get(fc.id()) != null && !fcMeterMap.get(fc.id()).isEmpty()) {
+                fcMeterMap.get(fc.id()).forEach(devMeterPair -> {
+                    if (devMeterPair.getLeft().equals(deviceId)) {
+                        filterTreatmentBuilder.meter(devMeterPair.getRight());
+                    }
+                });
+            }
+            // If a CE-VLAN-ID exists on the incoming packet then push an S-TAG of current FC on top
+            // otherwise push it on as a C-tag
+            if (ingressNi.ceVlanId() != null && ingressNi.ceVlanId() != VlanId.NONE) {
+                filterTreatmentBuilder.pushVlan(EthType.EtherType.QINQ.ethType()).setVlanId(fc.vlanId());
+            } else {
+                filterTreatmentBuilder.pushVlan().setVlanId(fc.vlanId());
+            }
+        }
+
+        filterObjBuilder.addCondition(filterVlanIdCriterion);
+
+
+
+        // Do not add meta if there are no instructions (i.e. if not first)
+        if (!(ingressNi.type().equals(Type.GENERIC))) {
+            filterObjBuilder.withMeta(filterTreatmentBuilder.build());
+        }
+
+        flowObjectiveService.filter(deviceId, filterObjBuilder.add());
+        flowObjectiveMap.get(fc.id()).addFirst(Pair.of(deviceId, filterObjBuilder.add()));
+
+        ////////////////////////////////////////////////////
+        // Prepare and submit next and forwarding objectives
+        ////////////////////////////////////////////////////
+
+        TrafficSelector.Builder fwdSelectorBuilder = DefaultTrafficSelector.builder()
+                .matchVlanId(fc.vlanId())
+                .matchInPort(portNumber);
+
+        if (isOfDpa(deviceId)) {
+            // workaround for OF-DPA
+            fwdSelectorBuilder.matchEthType(Ethernet.TYPE_IPV4);
+        }
+
+        TrafficSelector fwdSelector = fwdSelectorBuilder.build();
+
+        Integer nextId = flowObjectiveService.allocateNextId();
+
+        NextObjective.Type nextType = egressNiSet.size() == 1 ?
+                NextObjective.Type.SIMPLE : NextObjective.Type.BROADCAST;
+
+        // Setting higher priority to fwd/next objectives to bypass filter in case of match conflict in OVS switches
+        NextObjective.Builder nextObjectiveBuider = DefaultNextObjective.builder()
+                .fromApp(appId)
+                .makePermanent()
+                .withType(nextType)
+                .withPriority(PRIORITY + 1)
+                .withMeta(fwdSelector)
+                .withId(nextId);
+
+        egressNiSet.forEach(egressNi -> {
+            // TODO: Check if ingressNi and egressNi are on the same device?
+            TrafficTreatment.Builder nextTreatmentBuilder = DefaultTrafficTreatment.builder();
+            // If last NI in FC is not UNI,
+            // keep the existing S-TAG - it will be translated at the entrance of the next FC
+            if (egressNi.type().equals(CarrierEthernetNetworkInterface.Type.UNI)) {
+                nextTreatmentBuilder.popVlan();
+            }
+            Instruction outInstruction = Instructions.createOutput(egressNi.cp().port());
+            nextTreatmentBuilder.add(outInstruction);
+            nextObjectiveBuider.addTreatment(nextTreatmentBuilder.build());
+        });
+
+        NextObjective nextObjective = nextObjectiveBuider.add();
+
+        // Setting higher priority to fwd/next objectives to bypass filter in case of match conflict in OVS switches
+        ForwardingObjective forwardingObjective = DefaultForwardingObjective.builder()
+                .fromApp(appId)
+                .makePermanent()
+                .withFlag(ForwardingObjective.Flag.VERSATILE)
+                .withPriority(PRIORITY + 1)
+                .withSelector(fwdSelector)
+                .nextStep(nextId)
+                .add();
+
+        flowObjectiveService.next(ingressNi.cp().deviceId(), nextObjective);
+        // Add all NextObjectives at the end of the list so that they will be removed last
+        flowObjectiveMap.get(fc.id()).addLast(Pair.of(ingressNi.cp().deviceId(), nextObjective));
+
+        flowObjectiveService.forward(ingressNi.cp().deviceId(), forwardingObjective);
+        flowObjectiveMap.get(fc.id()).addFirst(Pair.of(ingressNi.cp().deviceId(), forwardingObjective));
+    }
+
+    @Override
+    public void createBandwidthProfileResources(CarrierEthernetForwardingConstruct fc, CarrierEthernetUni uni) {
+        log.info("Creating BW profile...{}", uni.toString());
+        // Create meters and add them to global MeterId map
+        Set<Pair<DeviceId, MeterId>> meters;
+
+        DeviceId deviceId = getEEDevice(fc, uni);
+
+        if (fcMeterMap.containsKey(fc.id())) {
+            meters = fcMeterMap.get(fc.id());
+        } else {
+            meters = new HashSet<>();
+            if (deviceId == null) {
+                // no meters
+                return;
+            }
+        }
+        meters.addAll(submitMeters(fc, uni, deviceId));
+        fcMeterMap.put(fc.id(), meters);
+    }
+
+    private boolean isOfDpa(DeviceId deviceId) {
+        Driver driver = drivers.getDriver(deviceId);
+        return driver != null &&
+                driver.swVersion().contains("OF-DPA");
+    }
+
+    // Maybe we still need this method to later modify the QoS profile of an FC
+    @Override
+    public void applyBandwidthProfileResources(CarrierEthernetForwardingConstruct fc, CarrierEthernetUni uni) {
+        log.info("Applying BW profile...");
+
+        DeviceId deviceId = eeDeviceMap.get(fc.id());
+        if (deviceId == null) {
+            log.warn("Trying to apply bandwidth profile rules" +
+                    "to not existing device/meters map");
+            return;
+        }
+
+        // Do not apply meters to NETCONF-controlled switches here since they should have been applied in the pipeline
+        // FIXME: Is there a better way to check this?
+        if (deviceId.uri().getScheme().equals("netconf")) {
+            return;
+        }
+
+        // Do not apply meters to OFDPA 2.0 switches since they are not currently supported
+        if (isOfDpa(deviceId)) {
+            return;
+        }
+
+        // Get installed flows with the same appId/deviceId with IN_PORT = UNI port which push the FC vlanId
+        List<FlowRule> flowRuleList =
+                StreamSupport.stream(flowRuleService.getFlowEntries(deviceId).spliterator(), false)
+                        .filter(flowRule -> flowRule.appId() == appId.id())
+                        .collect(Collectors.toList());
+                                //&& getPushedVlanFromTreatment(flowRule.treatment()).equals(fc.vlanId()))
+
+
+        // Apply meters to flows
+        for (FlowRule flowRule : flowRuleList) {
+            // Need to add to the flow the meters associated with the same device
+            Set<Pair<DeviceId, MeterId>> deviceMeterIdSet = new HashSet<>();
+
+            if (fcMeterMap.get(fc.id()) != null && !fcMeterMap.get(fc.id()).isEmpty()) {
+                fcMeterMap.get(fc.id()).forEach(devMeterPair -> {
+                    if (devMeterPair.getLeft().equals(flowRule.deviceId())) {
+                        deviceMeterIdSet.add(devMeterPair);
+                    }
+                });
+            }
+            // Modify and submit flow rule only if there are meters to add
+            if (!deviceMeterIdSet.isEmpty()) {
+                log.info("Applying metered flow rules...");
+                FlowRule newFlowRule = addMetersToFlowRule(flowRule, deviceMeterIdSet);
+                flowRuleService.applyFlowRules(newFlowRule);
+            }
+        }
+    }
+
+    private VlanId getPushedVlanFromTreatment(TrafficTreatment treatment) {
+        boolean pushVlan = false;
+        VlanId pushedVlan = null;
+        for (Instruction instruction : treatment.allInstructions()) {
+            if (instruction.type().equals(Instruction.Type.L2MODIFICATION)) {
+                L2ModificationInstruction l2ModInstr = (L2ModificationInstruction) instruction;
+                if (l2ModInstr.subtype().equals(L2ModificationInstruction.L2SubType.VLAN_PUSH)) {
+                    pushVlan = true;
+                } else if (l2ModInstr.subtype().equals(L2ModificationInstruction.L2SubType.VLAN_ID) && pushVlan) {
+                    pushedVlan = ((L2ModificationInstruction.ModVlanIdInstruction) instruction).vlanId();
+                }
+            }
+        }
+        return pushedVlan != null ? pushedVlan : VlanId.NONE;
+    }
+
+
+    /**
+     * 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<Pair<DeviceId, MeterId>> submitMeters(CarrierEthernetForwardingConstruct fc,
+                                                      CarrierEthernetUni uni, DeviceId deviceId) {
+        Set<Pair<DeviceId, MeterId>> meters = new HashSet<>();
+
+        uni.bwps().forEach(bwp -> {
+            log.info("bwp: {}", bwp.toString());
+
+            // KB_PER_SECOND
+            long longCir = (long) (bwp.cir().bps() / 8000);
+            long longEir = (long) (bwp.eir().bps() / 8000);
+            log.info("longCir: {}", longCir);
+            log.info("longEir: {}", longEir);
+
+            MeterRequest.Builder meterRequestBuilder;
+            Meter meter;
+            Band.Builder bandBuilder;
+
+            Set<Band> bandSet = new HashSet<>();
+
+            // If EIR is zero do not create the REMARK meter
+            /* === Centec v350 supports only DROP type! ===
+            if (longEir != 0) {
+                log.info("Enter here..");
+                // Mark frames that exceed CIR as Best Effort
+                bandBuilder = DefaultBand.builder()
+                        .ofType(Band.Type.REMARK)
+                        .withRate(longCir)
+                        .dropPrecedence((short) 0);
+
+                if (bwp.cbs() != 0) {
+                    bandBuilder.burstSize(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 (bwp.cbs() != 0 || bwp.ebs() != 0) {
+                    // FIXME: Use CBS and EBS correctly according to MEF specs
+                    bandBuilder.burstSize(bwp.cbs() + bwp.ebs());
+                }
+
+                bandSet.add(bandBuilder.build());
+            }
+
+            // Create meter only if at least one band was created
+            if (!bandSet.isEmpty()) {
+                meterRequestBuilder = DefaultMeterRequest.builder()
+                        .forDevice(deviceId)
+                        .fromApp(appId)
+                        .withUnit(Meter.Unit.KB_PER_SEC)
+                        .withBands(bandSet);
+
+                if (bwp.cbs() != 0 || bwp.ebs() != 0) {
+                    meterRequestBuilder.burst();
+                }
+
+                // Submit meter request and store
+                meter = meterService.submit(meterRequestBuilder.add());
+                // FIXME: use correct device id
+                log.info("Adding meter...{}", meter.toString());
+
+                meters.add(new ImmutablePair<>(deviceId, meter.id()));
+            }
+        });
+
+        return meters;
+    }
+
+    private FlowRule addMetersToFlowRule(FlowRule flowRule,  Set<Pair<DeviceId, MeterId>> deviceMeterIdSet) {
+
+        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment
+                .builder(flowRule.treatment());
+
+        deviceMeterIdSet.forEach(deviceMeterPair ->
+            tBuilder.meter(deviceMeterPair.getRight()));
+
+        return createFlowRule(flowRule.deviceId(), flowRule.priority(),
+                flowRule.selector(), tBuilder.build(), flowRule.tableId());
+    }
+
+    @Override
+    public void removeBandwidthProfileResources(CarrierEthernetForwardingConstruct fc, CarrierEthernetUni uni) {
+        removeMeters(fc, uni);
+    }
+
+    /**
+     * Removes the meters associated with a specific UNI of an FC.
+     *
+     * @param fc the forwarding construct
+     * @param uni the UNI descriptor
+     * */
+    private void removeMeters(CarrierEthernetForwardingConstruct fc, CarrierEthernetUni uni) {
+
+        if (!fcMeterMap.containsKey(fc.id())) {
+            return;
+        }
+
+        Set<Pair<DeviceId, MeterId>> ids = fcMeterMap.get(fc.id());
+
+        // Rebuild meter request based on existing meter, withdraw the request, and remove it from our internal storage
+        ids.stream()
+                .map(id -> meterService.getMeter(id.getLeft(), id.getRight()))
+                .filter(Objects::nonNull)
+                .forEach(meter -> {
+                    MeterRequest.Builder request = DefaultMeterRequest.builder()
+                            .fromApp(meter.appId())
+                            .forDevice(meter.deviceId())
+                            .withUnit(meter.unit())
+                            .withBands(meter.bands());
+                    if (uni.bwp().cbs() != 0 || uni.bwp().ebs() != 0) {
+                        request.burst();
+                    }
+                    meterService.withdraw(request.remove(), meter.id());
+
+                    ids.remove(new ImmutablePair<>(meter.deviceId(), meter.id()));
+                });
+    }
+
+    /**
+     * Removes all flow objectives installed by the application which are associated with a specific FC.
+     *
+     * @param fcId ForwardingConcrtuct object
+     */
+    @Override
+    public void removeAllForwardingResources(EvcConnId fcId) {
+        // Note: A Flow Rule cannot be shared by multiple FCs due to different VLAN or CE-VLAN ID match.
+        List<Pair<DeviceId, Objective>> flowObjectives = flowObjectiveMap.remove(fcId);
+        // NextObjectives will be removed after all other Objectives
+        // TODO: filter also on elements of pair
+        flowObjectives.stream()
+                .filter(Objects::nonNull)
+                .forEach(pair ->
+                        flowObjectiveService.apply(pair.getLeft(), pair.getRight().copy().remove()));
+    }
+
+    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();
+    }
+
+    /**
+     * !! Caution !! This method is strictly tied to the expected topology
+     * view of this {@link MetroNetworkVirtualNodeService} implementation.
+     * The UNI is expected to be in the CPE and meters implementation in the EE.
+     * The CPE node shall be connected only
+     * with the EE device (exception are multi path home gateway).
+     *
+     * @param fc forwarding construct
+     * @param uni User to Network Interface
+     * @return the EE device ID
+     */
+    private DeviceId getEEDevice(CarrierEthernetForwardingConstruct fc, CarrierEthernetUni uni)
+            throws IllegalStateException {
+        CarrierEthernetNetworkInterface realUni;
+        Optional<ConnectPoint> optCp =
+                bigSwitchService.connectPointFromVirtPort(uni.cp().port());
+        if (optCp.isPresent()) {
+            realUni = buildLocalNi(optCp.get(), uni);
+        } else {
+            log.info("Virtual ingress interface does not map to a local connect point");
+            throw new IllegalStateException("Virtual UNI interface does not map to a local connect point");
+        }
+        if (eeDeviceMap.get(fc.id()) != null) {
+            return eeDeviceMap.get(fc.id());
+        }
+        // find the (only) egress link of the UNI device
+        Optional<Link> optLink = linkService.getDeviceEgressLinks(realUni.cp().deviceId())
+                .stream().findFirst();
+        if (optLink.isPresent()) {
+
+            // the link destination should be our target EE device
+            DeviceId deviceId = optLink.get().dst().deviceId();
+            log.info("Adding EE device {} in memory...", deviceId.toString());
+            eeDeviceMap.put(fc.id(), deviceId);
+            return deviceId;
+        } else {
+            log.info("No EE device found for meters...uni: {}", realUni.cp().toString());
+            // in this case there is no EE upstream and so no meter will be installed
+            return null;
+        }
+    }
+}
\ No newline at end of file
diff --git a/local/ce-vee/src/main/java/org/opencord/ce/local/vee/package-info.java b/local/ce-vee/src/main/java/org/opencord/ce/local/vee/package-info.java
new file mode 100644
index 0000000..c8ee47d
--- /dev/null
+++ b/local/ce-vee/src/main/java/org/opencord/ce/local/vee/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Virtual Ethernet Edge implementation.
+ */
+package org.opencord.ce.local.vee;
\ No newline at end of file
