diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/IntentInstaller.java b/apps/vpls/src/main/java/org/onosproject/vpls/IntentInstaller.java
index 79ed713..52a3924 100644
--- a/apps/vpls/src/main/java/org/onosproject/vpls/IntentInstaller.java
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/IntentInstaller.java
@@ -15,18 +15,18 @@
  */
 package org.onosproject.vpls;
 
-import com.google.common.collect.SetMultimap;
-import org.apache.commons.lang3.tuple.Pair;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
 import org.onlab.packet.MacAddress;
-import org.onlab.packet.VlanId;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.FilteredConnectPoint;
+import org.onosproject.net.Host;
 import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
 import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.TrafficTreatment;
 import org.onosproject.net.intent.Intent;
 import org.onosproject.net.intent.IntentService;
+import org.onosproject.net.intent.IntentState;
 import org.onosproject.net.intent.Key;
 import org.onosproject.net.intent.MultiPointToSinglePointIntent;
 import org.onosproject.net.intent.SinglePointToMultiPointIntent;
@@ -34,24 +34,37 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 import java.util.Set;
-import java.util.stream.Collectors;
 
 /**
  * Synchronizes intents between the in-memory intent store and the
  * IntentService.
  */
 public class IntentInstaller {
+    private static final String SUBMIT =
+            "Submitting intents to the Intent Synchronizer";
+    private static final String WITHDRAW =
+            "Withdrawing intents to the Intent Synchronizer";
+    private static final String SP2MP =
+            "Building sp2mp intent from {}";
+    private static final String MP2SP =
+            "Building mp2sp intent to {}";
+
     private static final Logger log = LoggerFactory.getLogger(
             IntentInstaller.class);
 
     private static final int PRIORITY_OFFSET = 1000;
 
-    private static final String PREFIX_BROADCAST = "brc";
-    private static final String PREFIX_UNICAST = "uni";
+    private static final Set<IntentState> WITHDRAWN_INTENT_STATES =
+            ImmutableSet.of(IntentState.WITHDRAWN,
+                            IntentState.WITHDRAW_REQ,
+                            IntentState.WITHDRAWING);
+
+    static final String PREFIX_BROADCAST = "brc";
+    static final String PREFIX_UNICAST = "uni";
+    static final String DASH = "-";
 
     private final ApplicationId appId;
     private final IntentSynchronizationService intentSynchronizer;
@@ -72,173 +85,150 @@
     }
 
     /**
-     * Formats the requests for creating and submit intents.
-     * Single Points to Multi Point intents are created for all the configured
-     * Connect Points. Multi Point to Single Point intents are created for
-     * Connect Points configured that have hosts attached.
-     *
-     * @param confHostPresentCPoint A map of Connect Points with the eventual
-     *                              MAC address of the host attached, by VLAN
-     */
-    protected void installIntents(SetMultimap<VlanId,
-            Pair<ConnectPoint,
-                    MacAddress>> confHostPresentCPoint) {
-        List<Intent> intents = new ArrayList<>();
-
-        confHostPresentCPoint.keySet()
-                .stream()
-                .filter(vlanId -> confHostPresentCPoint.get(vlanId) != null)
-                .forEach(vlanId -> {
-                    Set<Pair<ConnectPoint, MacAddress>> cPoints =
-                            confHostPresentCPoint.get(vlanId);
-                    cPoints.forEach(cPoint -> {
-                        MacAddress mac = cPoint.getValue();
-                        ConnectPoint src = cPoint.getKey();
-                        Set<ConnectPoint> dsts = cPoints.stream()
-                                .map(Pair::getKey)
-                                .filter(cp -> !cp.equals(src))
-                                .collect(Collectors.toSet());
-                        Key brcKey = buildKey(PREFIX_BROADCAST, src, vlanId);
-
-                        if (dsts.isEmpty()) {
-                            return;
-                        }
-
-                        intents.add(buildBrcIntent(brcKey, src, dsts, vlanId));
-
-                        if (mac != null && countMacInCPoints(cPoints) > 1) {
-                            Key uniKey = buildKey(PREFIX_UNICAST, src, vlanId);
-                            MultiPointToSinglePointIntent uniIntent =
-                                    buildUniIntent(uniKey,
-                                                   dsts,
-                                                   src,
-                                                   vlanId,
-                                                   mac);
-                            intents.add(uniIntent);
-                        }
-                    });
-                });
-        submitIntents(intents);
-    }
-
-    /**
      * Requests to install the intents passed as argument to the Intent Service.
      *
      * @param intents intents to be submitted
      */
-    private void submitIntents(Collection<Intent> intents) {
-        log.debug("Submitting intents to the Intent Synchronizer");
-        intents.forEach(intent -> {
-            intentSynchronizer.submit(intent);
-        });
+    protected void submitIntents(Collection<Intent> intents) {
+        log.debug(SUBMIT);
+        intents.forEach(intentSynchronizer::submit);
     }
 
     /**
-     * Builds a Single Point to Multi Point intent.
+     * Requests to withdraw the intents passed as argument to the Intent Service.
      *
-     * @param src  The source Connect Point
-     * @param dsts The destination Connect Points
-     * @return Single Point to Multi Point intent generated.
+     * @param intents intents to be withdraw
      */
-    private SinglePointToMultiPointIntent buildBrcIntent(Key key,
-                                                         ConnectPoint src,
-                                                         Set<ConnectPoint> dsts,
-                                                         VlanId vlanId) {
-        log.debug("Building p2mp intent from {}", src);
+    protected void withdrawIntents(Collection<Intent> intents) {
+        log.debug(WITHDRAW);
+        intents.forEach(intentSynchronizer::withdraw);
+    }
+
+    /**
+     * Returns list of intents belongs to a VPLS.
+     *
+     * @param name required VPLS network name
+     * @return list of intents belongs to a VPLS
+     */
+    protected List<Intent> getIntentsFromVpls(String name) {
+        List<Intent> intents = Lists.newArrayList();
+
+        intentService.getIntents().forEach(intent -> {
+            if (intent.key().toString().startsWith(name)) {
+                intents.add(intent);
+            }
+        });
+
+        return intents;
+    }
+
+    /**
+     * Builds a broadcast intent.
+     *
+     * @param key key to identify the intent
+     * @param src the source connect point
+     * @param dsts the destination connect points
+     * @return the generated single-point to multi-point intent
+     */
+    protected SinglePointToMultiPointIntent buildBrcIntent(Key key,
+                                                           FilteredConnectPoint src,
+                                                           Set<FilteredConnectPoint> dsts) {
+        log.debug(SP2MP, src);
 
         SinglePointToMultiPointIntent intent;
 
-        TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
-
-        TrafficSelector.Builder builder = DefaultTrafficSelector.builder()
+        TrafficSelector selector = DefaultTrafficSelector.builder()
                 .matchEthDst(MacAddress.BROADCAST)
-                .matchVlanId(vlanId);
-
-        TrafficSelector selector = builder.build();
+                .build();
 
         intent = SinglePointToMultiPointIntent.builder()
                 .appId(appId)
                 .key(key)
                 .selector(selector)
-                .treatment(treatment)
-                .ingressPoint(src)
-                .egressPoints(dsts)
+                .filteredIngressPoint(src)
+                .filteredEgressPoints(dsts)
                 .priority(PRIORITY_OFFSET)
                 .build();
         return intent;
     }
 
     /**
-     * Builds a Multi Point to Single Point intent.
+     * Builds a unicast intent.
      *
-     * @param srcs The source Connect Points
-     * @param dst  The destination Connect Point
-     * @return Multi Point to Single Point intent generated.
+     * @param key key to identify the intent
+     * @param srcs the source Connect Points
+     * @param dst the destination Connect Point
+     * @param host destination Host
+     * @return the generated multi-point to single-point intent
      */
-    private MultiPointToSinglePointIntent buildUniIntent(Key key,
-                                                         Set<ConnectPoint> srcs,
-                                                         ConnectPoint dst,
-                                                         VlanId vlanId,
-                                                         MacAddress mac) {
-        log.debug("Building mp2p intent to {}", dst);
+    protected MultiPointToSinglePointIntent buildUniIntent(Key key,
+                                                           Set<FilteredConnectPoint> srcs,
+                                                           FilteredConnectPoint dst,
+                                                           Host host) {
+        log.debug(MP2SP, dst);
 
-        MultiPointToSinglePointIntent intent;
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchEthDst(host.mac())
+                .build();
 
-        TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
 
-        TrafficSelector.Builder builder = DefaultTrafficSelector.builder()
-                .matchEthDst(mac)
-                .matchVlanId(vlanId);
-
-        TrafficSelector selector = builder.build();
-
-        intent = MultiPointToSinglePointIntent.builder()
+        return MultiPointToSinglePointIntent.builder()
                 .appId(appId)
                 .key(key)
                 .selector(selector)
-                .treatment(treatment)
-                .ingressPoints(srcs)
-                .egressPoint(dst)
+                .filteredIngressPoints(srcs)
+                .filteredEgressPoint(dst)
                 .priority(PRIORITY_OFFSET)
                 .build();
-        return intent;
+
     }
 
     /**
-     * Builds an intent Key for either for a Single Point to Multi Point or
-     * Multi Point to Single Point intent, based on a prefix that defines
+     * Builds an intent Key for either for a single-point to multi-point or
+     * multi-point to single-point intent, based on a prefix that defines
      * the type of intent, the single connection point representing the source
-     * or the destination and the vlan id representing the network.
+     * or the destination and the VLAN identifier representing the network.
      *
-     * @param cPoint the source or destination connect point
-     * @param vlanId the network vlan id
-     * @param prefix prefix string
-     * @return
+     * @param prefix key prefix
+     * @param cPoint connect point for single source/destination
+     * @param networkName VPLS network name
+     * @param hostMac source/destination mac address
+     * @return key to identify the intent
      */
-    private Key buildKey(String prefix, ConnectPoint cPoint, VlanId vlanId) {
-        String keyString = new StringBuilder()
-                .append(prefix)
-                .append("-")
-                .append(cPoint.deviceId())
-                .append("-")
-                .append(cPoint.port())
-                .append("-")
-                .append(vlanId)
-                .toString();
+    protected Key buildKey(String prefix,
+                           ConnectPoint cPoint,
+                           String networkName,
+                           MacAddress hostMac) {
+        String keyString = networkName +
+                DASH +
+                prefix +
+                DASH +
+                cPoint.deviceId() +
+                DASH +
+                cPoint.port() +
+                DASH +
+                hostMac;
 
         return Key.of(keyString, appId);
     }
 
     /**
-     * Counts the number of mac addresses associated to a specific list of
-     * ConnectPoint.
+     * Returns true if the specified intent exists; false otherwise.
      *
-     * @param cPoints Set of ConnectPoints, eventually bound to the MAC of the
-     *                host attached
-     * @return number of mac addresses found.
+     * @param intentKey intent key
+     * @return true if the intent exists, false otherwise
      */
-    private int countMacInCPoints(Set<Pair<ConnectPoint, MacAddress>> cPoints) {
-        return (int) cPoints.stream().filter(p -> p.getValue() != null).count();
-    }
+    protected boolean intentExists(Key intentKey) {
+        if (intentService.getIntent(intentKey) == null) {
+            return false;
+        }
 
+        // Intent does not exist if intent withdrawn
+        IntentState currentIntentState = intentService.getIntentState(intentKey);
+        if (WITHDRAWN_INTENT_STATES.contains(currentIntentState)) {
+            return false;
+        }
+
+        return true;
+    }
 }
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/Vpls.java b/apps/vpls/src/main/java/org/onosproject/vpls/Vpls.java
index 2951d13..4e4bd4b 100644
--- a/apps/vpls/src/main/java/org/onosproject/vpls/Vpls.java
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/Vpls.java
@@ -15,10 +15,10 @@
  */
 package org.onosproject.vpls;
 
-import com.google.common.collect.HashMultimap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
 import com.google.common.collect.SetMultimap;
-
-import org.apache.commons.lang3.tuple.Pair;
+import com.google.common.collect.Sets;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
@@ -29,29 +29,56 @@
 import org.onosproject.app.ApplicationService;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
+import org.onosproject.incubator.net.intf.Interface;
 import org.onosproject.incubator.net.intf.InterfaceEvent;
 import org.onosproject.incubator.net.intf.InterfaceListener;
 import org.onosproject.incubator.net.intf.InterfaceService;
-import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.FilteredConnectPoint;
 import org.onosproject.net.Host;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.config.NetworkConfigService;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.VlanIdCriterion;
 import org.onosproject.net.host.HostEvent;
 import org.onosproject.net.host.HostListener;
 import org.onosproject.net.host.HostService;
+import org.onosproject.net.intent.Intent;
 import org.onosproject.net.intent.IntentService;
+import org.onosproject.net.intent.Key;
 import org.onosproject.routing.IntentSynchronizationService;
+import org.onosproject.vpls.config.VplsConfigurationService;
 import org.slf4j.Logger;
 
-import java.util.Map;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import static org.slf4j.LoggerFactory.getLogger;
+import static org.onosproject.vpls.IntentInstaller.PREFIX_BROADCAST;
+import static org.onosproject.vpls.IntentInstaller.PREFIX_UNICAST;
 
 /**
  * Application to create L2 broadcast overlay networks using VLAN.
  */
 @Component(immediate = true)
 public class Vpls {
-    protected static final String VPLS_APP = "org.onosproject.vpls";
+    /**
+     * Application name of VPLS.
+     */
+    static final String VPLS_APP = "org.onosproject.vpls";
+
+    private static final String HOST_FCP_NOT_FOUND =
+            "Filtered connected point for host {} not found";
+    private static final String HOST_EVENT = "Received HostEvent {}";
+    private static final String INTF_CONF_EVENT =
+            "Received InterfaceConfigEvent {}";
+    private static final String NET_CONF_EVENT =
+            "Received NetworkConfigEvent {}";
 
     private final Logger log = getLogger(getClass());
 
@@ -73,11 +100,20 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected IntentSynchronizationService intentSynchronizer;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigService configService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected VplsConfigurationService vplsConfigService;
+
     private final HostListener hostListener = new InternalHostListener();
 
     private final InternalInterfaceListener interfaceListener
             = new InternalInterfaceListener();
 
+    private final InternalNetworkConfigListener configListener =
+            new InternalNetworkConfigListener();
+
     private IntentInstaller intentInstaller;
 
     private ApplicationId appId;
@@ -97,111 +133,250 @@
 
         hostService.addListener(hostListener);
         interfaceService.addListener(interfaceListener);
+        configService.addListener(configListener);
 
-        setupConnectivity();
+        setupConnectivity(false);
 
         log.info("Activated");
     }
 
     @Deactivate
     public void deactivate() {
+        configService.removeListener(configListener);
         intentSynchronizer.removeIntentsByAppId(appId);
         log.info("Deactivated");
     }
 
-    protected void setupConnectivity() {
-        /*
-         * Parse Configuration and get Connect Point by VlanId.
-         */
-        SetMultimap<VlanId, ConnectPoint> confCPointsByVlan = getConfigCPoints();
+    /**
+     * Sets up connectivity for all VPLSs.
+     *
+     * @param isNetworkConfigEvent true if this function is triggered
+     *                             by NetworkConfigEvent; false otherwise
+     */
+    private void setupConnectivity(boolean isNetworkConfigEvent) {
+        SetMultimap<String, Interface> networkInterfaces =
+                vplsConfigService.getVplsNetworks();
 
-        /*
-         * Check that configured Connect Points have hosts attached and
-         * associate their Mac Address to the Connect Points configured.
-         */
-        SetMultimap<VlanId, Pair<ConnectPoint, MacAddress>> confHostPresentCPoint =
-                pairAvailableHosts(confCPointsByVlan);
+        Set<String> vplsAffectedByApi =
+                new HashSet<>(vplsConfigService.getVplsAffectedByApi());
 
-        /*
-         * Create and submit intents between the Connect Points.
-         * Intents for broadcast between all the configured Connect Points.
-         * Intents for unicast between all the configured Connect Points with
-         * hosts attached.
-         */
-        intentInstaller.installIntents(confHostPresentCPoint);
+        if (isNetworkConfigEvent && vplsAffectedByApi.isEmpty()) {
+            vplsAffectedByApi.addAll(vplsConfigService.getOldVpls());
+        }
 
+        networkInterfaces.asMap().forEach((networkName, interfaces) -> {
+            Set<Host> hosts = Sets.newHashSet();
+            interfaces.forEach(intf -> {
+                // Add hosts that belongs to the specific VPLS
+                hostService.getConnectedHosts(intf.connectPoint())
+                        .stream()
+                        .filter(host -> host.vlan().equals(intf.vlan()))
+                        .forEach(hosts::add);
+            });
+
+            setupConnectivity(networkName, interfaces, hosts,
+                    vplsAffectedByApi.contains(networkName));
+            vplsAffectedByApi.remove(networkName);
+        });
+
+        if (!vplsAffectedByApi.isEmpty()) {
+            for (String networkName:vplsAffectedByApi) {
+                withdrawIntents(networkName, Lists.newArrayList());
+            }
+        }
     }
 
     /**
-     * Computes the list of configured interfaces with a VLAN Id.
+     * Sets up connectivity for specific VPLS.
      *
-     * @return the interfaces grouped by vlan id
+     * @param networkName the VPLS name
+     * @param interfaces the interfaces that belong to the VPLS
+     * @param hosts the hosts that belong to the VPLS
+     * @param affectedByApi true if this function is triggered from the APIs;
+     *                      false otherwise
      */
-    protected SetMultimap<VlanId, ConnectPoint> getConfigCPoints() {
-        log.debug("Checking interface configuration");
+    private void setupConnectivity(String networkName,
+                                   Collection<Interface> interfaces,
+                                   Set<Host> hosts,
+                                   boolean affectedByApi) {
+        List<Intent> intents = Lists.newArrayList();
+        List<Key> keys = Lists.newArrayList();
+        Set<FilteredConnectPoint> fcPoints = buildFCPoints(interfaces);
 
-        SetMultimap<VlanId, ConnectPoint> confCPointsByVlan =
-                HashMultimap.create();
+        intents.addAll(buildUnicastIntents(
+                networkName, hosts, fcPoints, affectedByApi));
+        intents.addAll(buildBroadcastIntents(
+                networkName, fcPoints, affectedByApi));
 
-        interfaceService.getInterfaces()
-                .stream()
-                .filter(intf -> intf.ipAddressesList().isEmpty())
-                .forEach(intf -> confCPointsByVlan.put(intf.vlan(), intf.connectPoint()));
-        return confCPointsByVlan;
+        if (affectedByApi) {
+            intents.forEach(intent -> keys.add(intent.key()));
+            withdrawIntents(networkName, keys);
+        }
+
+        intentInstaller.submitIntents(intents);
     }
 
     /**
-     * Checks if for any ConnectPoint configured there's an host presents
-     * and in case it associates them together.
+     * Withdraws intents belonging to a VPLS, given a VPLS name.
      *
-     * @param confCPointsByVlan the configured ConnectPoints grouped by VLAN Id
-     * @return the configured ConnectPoints with eventual hosts associated.
+     * @param networkName the VPLS name
+     * @param keys the keys of the intents to be installed
      */
-    protected SetMultimap<VlanId, Pair<ConnectPoint, MacAddress>> pairAvailableHosts(
-            SetMultimap<VlanId, ConnectPoint> confCPointsByVlan) {
-        log.debug("Binding connected hosts MAC addresses");
+    private void withdrawIntents(String networkName,
+                                 List<Key> keys) {
+        List<Intent> intents = Lists.newArrayList();
 
-        SetMultimap<VlanId, Pair<ConnectPoint, MacAddress>> confHostPresentCPoint =
-                HashMultimap.create();
+        intentInstaller.getIntentsFromVpls(networkName)
+                .forEach(intent -> {
+                    if (!keys.contains(intent.key())) {
+                        intents.add(intent);
+                    }
+        });
 
-        confCPointsByVlan.entries()
-                .forEach(e -> bindMacAddr(e, confHostPresentCPoint));
-
-        return confHostPresentCPoint;
+        intentInstaller.withdrawIntents(intents);
     }
 
-    // Bind VLAN Id with hosts and connect points
-    private void bindMacAddr(Map.Entry<VlanId, ConnectPoint> e,
-                             SetMultimap<VlanId, Pair<ConnectPoint,
-                                     MacAddress>> confHostPresentCPoint) {
-        VlanId vlanId = e.getKey();
-        ConnectPoint cp = e.getValue();
-        Set<Host> connectedHosts = hostService.getConnectedHosts(cp);
-        connectedHosts.forEach(host -> {
-            if (host.vlan().equals(vlanId)) {
-                confHostPresentCPoint.put(vlanId, Pair.of(cp, host.mac()));
-            } else {
-                confHostPresentCPoint.put(vlanId, Pair.of(cp, null));
+    /**
+     * Sets up broadcast intents between any given filtered connect point.
+     *
+     * @param networkName the VPLS name
+     * @param fcPoints the set of filtered connect points
+     * @param affectedByApi true if the function triggered from APIs;
+     *                      false otherwise
+     * @return the set of broadcast intents
+     */
+    private Set<Intent> buildBroadcastIntents(String networkName,
+                                              Set<FilteredConnectPoint> fcPoints,
+                                              boolean affectedByApi) {
+        Set<Intent> intents = Sets.newHashSet();
+        fcPoints.forEach(point -> {
+            Set<FilteredConnectPoint> otherPoints =
+                    fcPoints.stream()
+                            .filter(fcp -> !fcp.equals(point))
+                            .collect(Collectors.toSet());
+
+            Key brcKey = intentInstaller.buildKey(PREFIX_BROADCAST,
+                                                  point.connectPoint(),
+                                                  networkName,
+                                                  MacAddress.BROADCAST);
+
+            if ((!intentInstaller.intentExists(brcKey) || affectedByApi) &&
+                    !otherPoints.isEmpty()) {
+                intents.add(intentInstaller.buildBrcIntent(brcKey,
+                                                           point,
+                                                           otherPoints));
             }
         });
-        if (connectedHosts.isEmpty()) {
-            confHostPresentCPoint.put(vlanId, Pair.of(cp, null));
-        }
+
+        return ImmutableSet.copyOf(intents);
+    }
+
+    /**
+     * Sets up unicast intents between any given filtered connect point.
+     *
+     * @param networkName the VPLS name
+     * @param hosts the set of destination hosts
+     * @param fcPoints the set of filtered connect points
+     * @param affectedByApi true if the function triggered from APIs;
+     *                      false otherwise
+     * @return the set of unicast intents
+     */
+    private Set<Intent> buildUnicastIntents(String networkName,
+                                            Set<Host> hosts,
+                                            Set<FilteredConnectPoint> fcPoints,
+                                            boolean affectedByApi) {
+        Set<Intent> intents = Sets.newHashSet();
+        hosts.forEach(host -> {
+            FilteredConnectPoint hostPoint = getHostPoint(host, fcPoints);
+
+            if (hostPoint == null) {
+                log.warn(HOST_FCP_NOT_FOUND, host);
+                return;
+            }
+
+            Set<FilteredConnectPoint> otherPoints =
+                    fcPoints.stream()
+                            .filter(fcp -> !fcp.equals(hostPoint))
+                            .collect(Collectors.toSet());
+
+            Key uniKey = intentInstaller.buildKey(PREFIX_UNICAST,
+                                                  host.location(),
+                                                  networkName,
+                                                  host.mac());
+
+            if ((!intentInstaller.intentExists(uniKey) || affectedByApi) &&
+                    !otherPoints.isEmpty()) {
+                intents.add(intentInstaller.buildUniIntent(uniKey,
+                                                           otherPoints,
+                                                           hostPoint,
+                                                           host));
+            }
+        });
+
+        return ImmutableSet.copyOf(intents);
+    }
+
+    /**
+     * Finds the filtered connect point a host is attached to.
+     *
+     * @param host the target host
+     * @param fcps the filtered connected points
+     * @return null if not found; the filtered connect point otherwise
+     */
+    private FilteredConnectPoint getHostPoint(Host host,
+                                              Set<FilteredConnectPoint> fcps) {
+        return fcps.stream()
+                .filter(fcp -> fcp.connectPoint().equals(host.location()))
+                .filter(fcp -> {
+                    VlanIdCriterion vlanCriterion =
+                            (VlanIdCriterion) fcp.trafficSelector().
+                                    getCriterion(Criterion.Type.VLAN_VID);
+
+                    return vlanCriterion != null &&
+                            vlanCriterion.vlanId().equals(host.vlan());
+                })
+                .findFirst()
+                .orElse(null);
+    }
+
+    /**
+     * Computes a set of filtered connect points from a list of given interfaces.
+     *
+     * @param interfaces the interfaces to compute
+     * @return the set of filtered connect points
+     */
+    private Set<FilteredConnectPoint> buildFCPoints(Collection<Interface> interfaces) {
+        // Build all filtered connected points in the network
+        return interfaces
+                .stream()
+                .map(intf -> {
+                    TrafficSelector.Builder selectorBuilder =
+                            DefaultTrafficSelector.builder();
+
+                    if (!intf.vlan().equals(VlanId.NONE)) {
+                        selectorBuilder.matchVlanId(intf.vlan());
+                    }
+
+                    return new FilteredConnectPoint(intf.connectPoint(),
+                                                    selectorBuilder.build());
+                })
+                .collect(Collectors.toSet());
     }
 
     /**
      * Listener for host events.
      */
-    class InternalHostListener implements HostListener {
+    private class InternalHostListener implements HostListener {
         @Override
         public void event(HostEvent event) {
-            log.debug("Received HostEvent {}", event);
+            log.debug(HOST_EVENT, event);
             switch (event.type()) {
                 case HOST_ADDED:
                 case HOST_UPDATED:
                 case HOST_REMOVED:
-                    setupConnectivity();
+                    setupConnectivity(false);
                     break;
+
                 default:
                     break;
             }
@@ -214,16 +389,39 @@
     private class InternalInterfaceListener implements InterfaceListener {
         @Override
         public void event(InterfaceEvent event) {
-            log.debug("Received InterfaceConfigEvent {}", event);
+            log.debug(INTF_CONF_EVENT, event);
             switch (event.type()) {
                 case INTERFACE_ADDED:
                 case INTERFACE_UPDATED:
                 case INTERFACE_REMOVED:
-                    setupConnectivity();
+                    setupConnectivity(false);
                     break;
+
                 default:
                     break;
             }
         }
     }
+
+    /**
+     * Listener for VPLS configuration events.
+     */
+    private class InternalNetworkConfigListener implements NetworkConfigListener {
+        @Override
+        public void event(NetworkConfigEvent event) {
+            if (event.configClass() == VplsConfigurationService.CONFIG_CLASS) {
+                log.debug(NET_CONF_EVENT, event.configClass());
+                switch (event.type()) {
+                    case CONFIG_ADDED:
+                    case CONFIG_UPDATED:
+                    case CONFIG_REMOVED:
+                        setupConnectivity(true);
+                        break;
+
+                    default:
+                        break;
+                }
+            }
+        }
+    }
 }
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/config/VplsConfig.java b/apps/vpls/src/main/java/org/onosproject/vpls/config/VplsConfig.java
new file mode 100644
index 0000000..f8323ef
--- /dev/null
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/config/VplsConfig.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vpls.config;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.JsonNodeFactory;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.Sets;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.config.Config;
+
+import java.util.Set;
+
+/**
+ * Configuration object for VPLS config.
+ */
+public class VplsConfig extends Config<ApplicationId> {
+    private static final String VPLS = "vplsNetworks";
+    private static final String NAME = "name";
+    private static final String INTERFACE = "interfaces";
+
+    /**
+     * Returns a set of configured VPLSs.
+     *
+     * @return set of VPLSs
+     */
+    public Set<VplsNetworkConfig> vplsNetworks() {
+        Set<VplsNetworkConfig> vpls = Sets.newHashSet();
+
+        JsonNode vplsNode = object.get(VPLS);
+
+        if (vplsNode == null) {
+            return vpls;
+        }
+
+        vplsNode.forEach(jsonNode -> {
+            Set<String> ifaces = Sets.newHashSet();
+            jsonNode.path(INTERFACE).forEach(ifacesNode ->
+                    ifaces.add(ifacesNode.asText())
+            );
+
+            String name = jsonNode.get(NAME).asText();
+
+            vpls.add(new VplsNetworkConfig(name, ifaces));
+        });
+
+        return vpls;
+    }
+
+    /**
+     * Returns the VPLS configuration given a VPLS name.
+     *
+     * @param name the VPLS name
+     * @return the VPLS configuration if it exists; null otherwise
+     */
+    public VplsNetworkConfig getVplsWithName(String name) {
+        for (VplsNetworkConfig vpls : vplsNetworks()) {
+            if (vpls.name().equals(name)) {
+                return vpls;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Adds a VPLS to the configuration.
+     *
+     * @param name the name of the VPLS to be added
+     */
+    public void addVpls(VplsNetworkConfig name) {
+        ObjectNode vplsNode = JsonNodeFactory.instance.objectNode();
+
+        vplsNode.put(NAME, name.name());
+
+        ArrayNode ifacesNode = vplsNode.putArray(INTERFACE);
+        name.ifaces().forEach(ifacesNode::add);
+
+        ArrayNode vplsArray = vplsNetworks().isEmpty() ?
+                initVplsConfiguration() : (ArrayNode) object.get(VPLS);
+        vplsArray.add(vplsNode);
+    }
+
+    /**
+     * Removes a VPLS from the configuration.
+     *
+     * @param name the name of the VPLS to be removed
+     */
+    public void removeVpls(String name) {
+        ArrayNode vplsArray = (ArrayNode) object.get(VPLS);
+
+        for (int i = 0; i < vplsArray.size(); i++) {
+            if (vplsArray.get(i).hasNonNull(NAME) &&
+                    vplsArray.get(i).get(NAME).asText().equals(name)) {
+                vplsArray.remove(i);
+                return;
+            }
+        }
+    }
+
+    /**
+     * Finds a VPLS with a given network interface.
+     *
+     * @param iface the network interface
+     * @return the VPLS if found; null otherwise
+     */
+    public VplsNetworkConfig getVplsFromInterface(String iface) {
+        for (VplsNetworkConfig vpls : vplsNetworks()) {
+            if (vpls.isAttached(iface)) {
+                return vpls;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Adds a network interface to a VPLS.
+     *
+     * @param name the name of the VPLS
+     * @param iface the network interface to be added
+     */
+    public void addInterfaceToVpls(String name, String iface) {
+        JsonNode vplsNode = object.get(VPLS);
+        vplsNode.forEach(jsonNode -> {
+
+            if (hasNamedNode(jsonNode, name)) {
+                ArrayNode ifacesNode = (ArrayNode) jsonNode.get(INTERFACE);
+                for (int i = 0; i < ifacesNode.size(); i++) {
+                    if (ifacesNode.get(i).asText().equals(iface)) {
+                        return; // Interface already exists.
+                    }
+                }
+                ifacesNode.add(iface);
+            }
+        });
+    }
+
+    /**
+     * Removes a network interface from a VPLS.
+     *
+     * @param name the name of the VPLS
+     * @param iface the network interface to be removed
+     */
+    public void removeInterfaceFromVpls(VplsNetworkConfig name, String iface) {
+        JsonNode vplsNode = object.get(VPLS);
+        vplsNode.forEach(jsonNode -> {
+            if (hasNamedNode(jsonNode, name.name())) {
+                ArrayNode ifacesNode = (ArrayNode) jsonNode.get(INTERFACE);
+                for (int i = 0; i < ifacesNode.size(); i++) {
+                    if (ifacesNode.get(i).asText().equals(iface)) {
+                        ifacesNode.remove(i);
+                        return;
+                    }
+                }
+            }
+        });
+    }
+
+    /**
+     * States if a JSON node has a "name" attribute and if the value is equal to
+     * the name given.
+     *
+     * @param jsonNode the JSON node
+     * @param name the node name
+     * @return true if the JSON node has a "name" attribute with value equal to
+     * the name given; false otherwise
+     */
+    private boolean hasNamedNode(JsonNode jsonNode, String name) {
+        return jsonNode.hasNonNull(NAME) &&
+                jsonNode.get(NAME).asText().equals(name);
+    }
+
+    /**
+     * Creates an empty VPLS configuration.
+     *
+     * @return empty ArrayNode to store the VPLS configuration
+     */
+    private ArrayNode initVplsConfiguration() {
+        return object.putArray(VPLS);
+    }
+}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/config/VplsConfigurationService.java b/apps/vpls/src/main/java/org/onosproject/vpls/config/VplsConfigurationService.java
new file mode 100644
index 0000000..16cd4c4
--- /dev/null
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/config/VplsConfigurationService.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vpls.config;
+
+import com.google.common.collect.SetMultimap;
+import org.onlab.packet.VlanId;
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.net.ConnectPoint;
+
+import java.util.Set;
+
+/**
+ * Provides information about the VPLS configuration.
+ */
+public interface VplsConfigurationService {
+    Class<VplsConfig> CONFIG_CLASS = VplsConfig.class;
+
+    /**
+     * Adds a VPLS to the configuration.
+     *
+     * @param name the name of the VPLS
+     * @param ifaces the interfaces associated with the VPLS
+     */
+    void addVpls(String name, Set<String> ifaces);
+
+    /**
+     * Removes a VPLS from the configuration.
+     *
+     * @param name the name of the VPLS to be removed
+     */
+    void removeVpls(String name);
+
+    /**
+     * Adds a network interface to a VPLS.
+     *
+     * @param name the name of the VPLS
+     * @param iface the network interface to be added to the VPLS
+     */
+    void addInterfaceToVpls(String name, String iface);
+
+    /**
+     * Removes a network interface from a VPLS.
+     *
+     * @param iface the network interface to be removed from the VPLS
+     */
+    void removeInterfaceFromVpls(String iface);
+
+    /**
+     * Cleans up the VPLS configuration. Removes all VPLSs.
+     */
+    void cleanVpls();
+
+    /**
+     * Retrieves the VPLS names modified from CLI.
+     *
+     * @return a set of VPLS names modified from CLI
+     */
+    Set<String> getVplsAffectedByApi();
+    // TODO Removes this function after intent framework fix race condition
+
+    /**
+     * Retrieves the interfaces from the VPLS configuration.
+     *
+     * @return a set of interfaces contained in the VPLS configuration
+     */
+    Set<Interface> getAllInterfaces();
+
+    /**
+     * Retrieves the interfaces belonging to the VPLS.
+     *
+     * @param name the name of the VPLS
+     * @return a set of interfaces belonging to the VPLS
+     */
+    Set<Interface> getVplsInterfaces(String name);
+
+    /**
+     * Retrieves all VPLS names.
+     *
+     * @return a set of VPLS names
+     */
+    Set<String> getAllVpls();
+
+    /**
+     * Retrieves all VPLS names from the old config.
+     *
+     * @return a set of VPLS names
+     */
+    Set<String> getOldVpls();
+    // TODO Removes this function after intent framework fix race condition
+
+    /**
+     * Retrieves the VPLS names and associated interfaces from the configuration.
+     *
+     * @return a map VPLS names and associated interfaces
+     */
+    SetMultimap<String, Interface> getVplsNetworks();
+
+    /**
+     * Retrieves a VPLS network given a VLAN Id and a connect point.
+     *
+     * @param vlan the VLAN Id
+     * @param connectPoint the connect point
+     * @return a map VPLS names and associated interfaces; null otherwise
+     */
+    SetMultimap<String, Interface> getVplsNetwork(VlanId vlan,
+                                                 ConnectPoint connectPoint);
+}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/config/VplsNetworkConfig.java b/apps/vpls/src/main/java/org/onosproject/vpls/config/VplsNetworkConfig.java
new file mode 100644
index 0000000..b3c721b
--- /dev/null
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/config/VplsNetworkConfig.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vpls.config;
+
+import com.google.common.collect.ImmutableSet;
+
+import java.util.Objects;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Configuration of a VPLS Network.
+ */
+public class VplsNetworkConfig {
+    private final String name;
+    private final Set<String> ifaces;
+
+    /**
+     * Creates a new VPLS configuration.
+     *
+     * @param name the VPLS name
+     * @param ifaces the interfaces associated with the VPLS
+     */
+    public VplsNetworkConfig(String name, Set<String> ifaces) {
+        this.name = checkNotNull(name);
+        this.ifaces = checkNotNull(ImmutableSet.copyOf(ifaces));
+    }
+
+    /**
+     * Returns the name of the VPLS.
+     *
+     * @return the name of the VPLS
+     */
+    public String name() {
+        return name;
+    }
+
+    /**
+     * Returns the name of interfaces associated with the VPLS.
+     *
+     * @return a set of interface names associated with the VPLS
+     */
+    public Set<String> ifaces() {
+        return ImmutableSet.copyOf(ifaces);
+    }
+
+    /**
+     * States if a given interface is part of a VPLS.
+     *
+     * @param iface the interface attached to a VPLS
+     * @return true if the interface is associated to the VPLS; false otherwise
+     */
+    public boolean isAttached(String iface) {
+        return ifaces.stream().anyMatch(i -> i.equals(iface));
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof VplsNetworkConfig) {
+            final VplsNetworkConfig that = (VplsNetworkConfig) obj;
+            return Objects.equals(this.name, that.name) &&
+                    Objects.equals(this.ifaces, that.ifaces);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(name, ifaces);
+    }
+}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/config/impl/VplsConfigurationImpl.java b/apps/vpls/src/main/java/org/onosproject/vpls/config/impl/VplsConfigurationImpl.java
new file mode 100644
index 0000000..e977170
--- /dev/null
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/config/impl/VplsConfigurationImpl.java
@@ -0,0 +1,335 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vpls.config.impl;
+
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSetMultimap;
+import com.google.common.collect.SetMultimap;
+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.VlanId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.incubator.net.intf.InterfaceService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.config.NetworkConfigRegistry;
+import org.onosproject.net.config.NetworkConfigService;
+import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.ConfigFactory;
+import org.onosproject.net.config.basics.SubjectFactories;
+import org.onosproject.vpls.config.VplsConfig;
+import org.onosproject.vpls.config.VplsNetworkConfig;
+import org.onosproject.vpls.config.VplsConfigurationService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Implementation of VPLSConfigurationService which reads VPLS configuration
+ * from the network configuration service.
+ */
+@Component(immediate = true)
+@Service
+public class VplsConfigurationImpl implements VplsConfigurationService {
+    private static final String VPLS_APP = "org.onosproject.vpls";
+    private static final String VPLS = "vpls";
+    private static final String EMPTY = "";
+    private static final String CONFIG_NULL = "VPLS configuration not defined";
+    private static final String APP_ID_NULL = "VPLS application ID is null";
+    private static final String CONFIG_CHANGED = "VPLS configuration changed: {}";
+    private static final String CHECK_CONFIG =
+            "Checking the interface configuration";
+    private static final String NET_CONF_EVENT =
+            "Received NetworkConfigEvent {}";
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigRegistry registry;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected InterfaceService interfaceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigService configService;
+
+    private final Set<String> vplsAffectedByApi = new HashSet<>();
+
+    private VplsConfig vplsConfig = new VplsConfig();
+
+    private SetMultimap<String, String> ifacesOfVpls = HashMultimap.create();
+    private SetMultimap<String, String> oldIfacesOfVpls = HashMultimap.create();
+    private SetMultimap<String, Interface> vplsNetworks = HashMultimap.create();
+
+    private final InternalNetworkConfigListener configListener =
+            new InternalNetworkConfigListener();
+
+    private ConfigFactory<ApplicationId, VplsConfig> vplsConfigFactory =
+            new ConfigFactory<ApplicationId, VplsConfig>(
+                    SubjectFactories.APP_SUBJECT_FACTORY, VplsConfig.class, VPLS) {
+                @Override
+                public VplsConfig createConfig() {
+                    return new VplsConfig();
+                }
+            };
+
+    private ApplicationId vplsAppId;
+
+    @Activate
+    protected void active() {
+        configService.addListener(configListener);
+        registry.registerConfigFactory(vplsConfigFactory);
+        loadConfiguration();
+        log.info("Started");
+    }
+
+    @Deactivate
+    protected  void deactive() {
+        registry.unregisterConfigFactory(vplsConfigFactory);
+        configService.removeListener(configListener);
+        log.info("Stopped");
+    }
+
+    /**
+     * Retrieves the VPLS configuration from network configuration.
+     */
+    private void loadConfiguration() {
+        loadAppId();
+
+        vplsConfig = configService.getConfig(vplsAppId, VplsConfig.class);
+
+        if (vplsConfig == null) {
+            log.warn(CONFIG_NULL);
+            configService.addConfig(vplsAppId, VplsConfig.class);
+            return;
+        }
+
+        oldIfacesOfVpls = ifacesOfVpls;
+        ifacesOfVpls = getConfigInterfaces();
+        vplsNetworks = getConfigCPoints();
+        log.debug(CONFIG_CHANGED, ifacesOfVpls);
+    }
+
+    /**
+     * Retrieves the application identifier from core service.
+     */
+    private void loadAppId() {
+        vplsAppId = coreService.getAppId(VPLS_APP);
+        if (vplsAppId == null) {
+            log.warn(APP_ID_NULL);
+        }
+    }
+
+    /**
+     * Applies a given configuration to the VPLS application.
+     */
+    private void applyConfig(VplsConfig vplsConfig) {
+        loadAppId();
+        configService.applyConfig(vplsAppId, VplsConfig.class, vplsConfig.node());
+    }
+
+    /**
+     * Retrieves the VPLS names and associated interfaces names from the configuration.
+     *
+     * @return a map VPLS names and associated interface names
+     */
+    private SetMultimap<String, String> getConfigInterfaces() {
+        SetMultimap<String, String> confIntfByVpls =
+                HashMultimap.create();
+
+        vplsConfig.vplsNetworks().forEach(vpls -> {
+            if (vpls.ifaces().isEmpty()) {
+                confIntfByVpls.put(vpls.name(), EMPTY);
+            } else {
+                vpls.ifaces().forEach(iface -> confIntfByVpls.put(vpls.name(), iface));
+            }
+        });
+
+        return confIntfByVpls;
+    }
+
+    /**
+     * Retrieves the VPLS names and associated interfaces from the configuration.
+     *
+     * @return a map VPLS names and associated interfaces
+     */
+    private SetMultimap<String, Interface> getConfigCPoints() {
+        log.debug(CHECK_CONFIG);
+
+        SetMultimap<String, Interface> confCPointsByIntf =
+                HashMultimap.create();
+
+        ifacesOfVpls.entries().forEach(vpls -> {
+            interfaceService.getInterfaces()
+                    .stream()
+                    .filter(intf -> intf.ipAddressesList().isEmpty())
+                    .filter(intf -> intf.name().equals(vpls.getValue()))
+                    .forEach(intf -> confCPointsByIntf.put(vpls.getKey(), intf));
+        });
+
+        return confCPointsByIntf;
+    }
+
+    /**
+     * Listener for VPLS configuration events.
+     */
+    private class InternalNetworkConfigListener implements NetworkConfigListener {
+        @Override
+        public void event(NetworkConfigEvent event) {
+            if (event.configClass() == VplsConfigurationService.CONFIG_CLASS) {
+                log.debug(NET_CONF_EVENT, event.configClass());
+                switch (event.type()) {
+                    case CONFIG_ADDED:
+                    case CONFIG_UPDATED:
+                    case CONFIG_REMOVED:
+                        loadConfiguration();
+                        break;
+
+                    default:
+                        break;
+                }
+            }
+        }
+    }
+
+    @Override
+    public void addVpls(String name, Set<String> ifaces) {
+        VplsNetworkConfig vpls;
+
+        if (ifacesOfVpls.containsKey(name)) {
+            if (ifaces.isEmpty()) {
+                return;
+            }
+
+            ifaces.forEach(iface ->
+                    vplsConfig.addInterfaceToVpls(name, iface));
+        } else {
+            vpls = new VplsNetworkConfig(name, ifaces);
+            vplsConfig.addVpls(vpls);
+        }
+
+        vplsAffectedByApi.add(name);
+        applyConfig(vplsConfig);
+    }
+
+    @Override
+    public void removeVpls(String name) {
+        if (ifacesOfVpls.containsKey(name)) {
+            vplsConfig.removeVpls(name);
+            vplsAffectedByApi.add(name);
+            applyConfig(vplsConfig);
+        }
+    }
+
+    @Override
+    public void addInterfaceToVpls(String name, String iface) {
+        if (ifacesOfVpls.containsKey(name)) {
+            vplsConfig.addInterfaceToVpls(name, iface);
+            vplsAffectedByApi.add(name);
+            applyConfig(vplsConfig);
+        }
+    }
+
+    @Override
+    public void removeInterfaceFromVpls(String iface) {
+        if (ifacesOfVpls.containsValue(iface)) {
+            VplsNetworkConfig vpls = vplsConfig.getVplsFromInterface(iface);
+            vplsConfig.removeInterfaceFromVpls(vpls, iface);
+            vplsAffectedByApi.add(vpls.name());
+            applyConfig(vplsConfig);
+        }
+    }
+
+    @Override
+    public void cleanVpls() {
+        ifacesOfVpls.entries().forEach(e -> {
+            vplsConfig.removeVpls(e.getKey());
+            vplsAffectedByApi.add(e.getKey());
+        });
+        applyConfig(vplsConfig);
+    }
+
+    @Override
+    public Set<String> getVplsAffectedByApi() {
+        Set<String> vplsNames = ImmutableSet.copyOf(vplsAffectedByApi);
+
+        vplsAffectedByApi.clear();
+
+        return vplsNames;
+    }
+
+    @Override
+    public Set<Interface> getAllInterfaces() {
+        Set<Interface> allInterfaces = new HashSet<>();
+        vplsNetworks.values().forEach(allInterfaces::add);
+
+        return allInterfaces;
+    }
+
+    @Override
+    public Set<Interface> getVplsInterfaces(String name) {
+        Set<Interface> vplsInterfaces = new HashSet<>();
+        vplsNetworks.get(name).forEach(vplsInterfaces::add);
+
+        return vplsInterfaces;
+    }
+
+    @Override
+    public Set<String> getAllVpls() {
+        return ifacesOfVpls.keySet();
+    }
+
+    @Override
+    public Set<String> getOldVpls() {
+        return oldIfacesOfVpls.keySet();
+    }
+
+    @Override
+    public SetMultimap<String, Interface> getVplsNetworks() {
+        return ImmutableSetMultimap.copyOf(vplsNetworks);
+    }
+
+    @Override
+    public SetMultimap<String, Interface> getVplsNetwork(VlanId vlan,
+                                                        ConnectPoint connectPoint) {
+        String vplsNetworkName =
+                vplsNetworks.entries().stream()
+                        .filter(e -> e.getValue().connectPoint().equals(connectPoint))
+                        .filter(e -> e.getValue().vlan().equals(vlan))
+                        .map(e -> e.getKey())
+                        .findFirst()
+                        .orElse(null);
+        SetMultimap<String, Interface> result = HashMultimap.create();
+        if (vplsNetworkName != null && vplsNetworks.containsKey(vplsNetworkName)) {
+            vplsNetworks.get(vplsNetworkName)
+                    .forEach(intf -> result.put(vplsNetworkName, intf));
+            return result;
+        }
+        return null;
+    }
+}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/config/impl/package-info.java b/apps/vpls/src/main/java/org/onosproject/vpls/config/impl/package-info.java
new file mode 100644
index 0000000..3229c7b
--- /dev/null
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/config/impl/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Configuration implementation  to create L2 broadcast network using VLAN.
+ */
+package org.onosproject.vpls.config.impl;
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/config/package-info.java b/apps/vpls/src/main/java/org/onosproject/vpls/config/package-info.java
new file mode 100644
index 0000000..f080044
--- /dev/null
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/config/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Configuration to create L2 broadcast network using VLAN.
+ */
+package org.onosproject.vpls.config;
diff --git a/apps/vpls/src/test/java/org/onosproject/vpls/VplsTest.java b/apps/vpls/src/test/java/org/onosproject/vpls/VplsTest.java
index 8f0556c..178e1a8 100644
--- a/apps/vpls/src/test/java/org/onosproject/vpls/VplsTest.java
+++ b/apps/vpls/src/test/java/org/onosproject/vpls/VplsTest.java
@@ -16,14 +16,20 @@
 package org.onosproject.vpls;
 
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.stream.Collectors;
 
-import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.SetMultimap;
+import com.google.common.collect.HashMultimap;
 import com.google.common.collect.Maps;
+import com.google.common.collect.Lists;
+import com.google.common.collect.ImmutableSetMultimap;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -45,10 +51,12 @@
 import org.onosproject.net.HostId;
 import org.onosproject.net.HostLocation;
 import org.onosproject.net.PortNumber;
+import org.onosproject.net.FilteredConnectPoint;
+import org.onosproject.net.config.NetworkConfigService;
 import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
 import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.VlanIdCriterion;
 import org.onosproject.net.host.HostEvent;
 import org.onosproject.net.host.HostListener;
 import org.onosproject.net.host.HostService;
@@ -63,8 +71,7 @@
 import org.onosproject.net.provider.ProviderId;
 import org.onosproject.routing.IntentSynchronizationAdminService;
 import org.onosproject.routing.IntentSynchronizationService;
-
-import com.google.common.collect.Sets;
+import org.onosproject.vpls.config.VplsConfigurationService;
 
 import static java.lang.String.format;
 import static org.easymock.EasyMock.anyObject;
@@ -75,33 +82,23 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
+import static org.onosproject.vpls.IntentInstaller.PREFIX_BROADCAST;
+import static org.onosproject.vpls.IntentInstaller.PREFIX_UNICAST;
+
 /**
  * Tests for the {@link Vpls} class.
  */
 public class VplsTest {
-
-    private static final int NUM_DEVICES = 7;
-
-    private static final MacAddress MAC1 = MacAddress.valueOf("00:00:00:00:00:01");
-    private static final MacAddress MAC2 = MacAddress.valueOf("00:00:00:00:00:02");
-    private static final MacAddress MAC3 = MacAddress.valueOf("00:00:00:00:00:03");
-    private static final MacAddress MAC4 = MacAddress.valueOf("00:00:00:00:00:04");
-    private static final MacAddress MAC5 = MacAddress.valueOf("00:00:00:00:00:05");
-    private static final MacAddress MAC6 = MacAddress.valueOf("00:00:00:00:00:06");
-    private static final MacAddress MAC7 = MacAddress.valueOf("00:00:00:00:00:07");
-
-    private static final Ip4Address IP1 = Ip4Address.valueOf("192.168.1.1");
-    private static final Ip4Address IP2 = Ip4Address.valueOf("192.168.1.2");
+    private static final String APP_NAME = "org.onosproject.vpls";
+    private static final ApplicationId APPID = TestApplicationId.create(APP_NAME);
+    private static final String DASH = "-";
+    private static final int PRIORITY_OFFSET = 1000;
+    private static final String NET1 = "net1";
+    private static final String NET2 = "net2";
+    private static final String COMPARE = "Comparing %s to %s";
 
     private static final PortNumber P1 = PortNumber.portNumber(1);
 
-    private static final VlanId VLAN1 = VlanId.vlanId((short) 1);
-    private static final VlanId VLAN2 = VlanId.vlanId((short) 2);
-
-    private static final int PRIORITY_OFFSET = 1000;
-    private static final String PREFIX_BROADCAST = "brc";
-    private static final String PREFIX_UNICAST = "uni";
-
     private static final DeviceId DID1 = getDeviceId(1);
     private static final DeviceId DID2 = getDeviceId(2);
     private static final DeviceId DID3 = getDeviceId(3);
@@ -109,37 +106,100 @@
     private static final DeviceId DID5 = getDeviceId(5);
     private static final DeviceId DID6 = getDeviceId(6);
 
-    private static final ConnectPoint C1 = new ConnectPoint(DID1, P1);
-    private static final ConnectPoint C2 = new ConnectPoint(DID2, P1);
-    private static final ConnectPoint C3 = new ConnectPoint(DID3, P1);
-    private static final ConnectPoint C4 = new ConnectPoint(DID4, P1);
-    private static final ConnectPoint C5 = new ConnectPoint(DID5, P1);
-    private static final ConnectPoint C6 = new ConnectPoint(DID6, P1);
+    private static final ConnectPoint CP1 = new ConnectPoint(DID1, P1);
+    private static final ConnectPoint CP2 = new ConnectPoint(DID2, P1);
+    private static final ConnectPoint CP3 = new ConnectPoint(DID3, P1);
+    private static final ConnectPoint CP4 = new ConnectPoint(DID4, P1);
+    private static final ConnectPoint CP5 = new ConnectPoint(DID5, P1);
+    private static final ConnectPoint CP6 = new ConnectPoint(DID6, P1);
 
-    private static final HostId HID1 = HostId.hostId(MAC1, VLAN1);
-    private static final HostId HID2 = HostId.hostId(MAC2, VLAN1);
-    private static final HostId HID3 = HostId.hostId(MAC3, VLAN1);
-    private static final HostId HID4 = HostId.hostId(MAC4, VLAN2);
-    private static final HostId HID5 = HostId.hostId(MAC5, VLAN2);
-    private static final HostId HID6 = HostId.hostId(MAC6, VLAN2);
-    private static final HostId HID7 = HostId.hostId(MAC7, VlanId.NONE);
+    private static final VlanId VLAN100 = VlanId.vlanId((short) 100);
+    private static final VlanId VLAN200 = VlanId.vlanId((short) 200);
+    private static final VlanId VLAN300 = VlanId.vlanId((short) 300);
 
-    private ApplicationService applicationService;
-    private CoreService coreService;
-    private HostListener hostListener;
-    private Set<Host> hostsAvailable;
-    private HostService hostService;
-    private IntentService intentService;
-    private InterfaceService interfaceService;
-    private Vpls vpls;
+    private static final MacAddress MAC1 =
+            MacAddress.valueOf("00:00:00:00:00:01");
+    private static final MacAddress MAC2 =
+            MacAddress.valueOf("00:00:00:00:00:02");
+    private static final MacAddress MAC3 =
+            MacAddress.valueOf("00:00:00:00:00:03");
+    private static final MacAddress MAC4 =
+            MacAddress.valueOf("00:00:00:00:00:04");
+    private static final MacAddress MAC5 =
+            MacAddress.valueOf("00:00:00:00:00:05");
+    private static final MacAddress MAC6 =
+            MacAddress.valueOf("00:00:00:00:00:06");
+    private static final MacAddress MAC7 =
+            MacAddress.valueOf("00:00:00:00:00:07");
 
-    private static final String APP_NAME = "org.onosproject.vpls";
-    private static final ApplicationId APPID = TestApplicationId.create(APP_NAME);
+    private static final Ip4Address IP1 = Ip4Address.valueOf("192.168.1.1");
+    private static final Ip4Address IP2 = Ip4Address.valueOf("192.168.1.2");
+
+    private static final HostId HID1 = HostId.hostId(MAC1, VLAN100);
+    private static final HostId HID2 = HostId.hostId(MAC2, VLAN100);
+    private static final HostId HID3 = HostId.hostId(MAC3, VLAN200);
+    private static final HostId HID4 = HostId.hostId(MAC4, VLAN200);
+    private static final HostId HID5 = HostId.hostId(MAC5, VLAN300);
+    private static final HostId HID6 = HostId.hostId(MAC6, VLAN300);
+    private static final HostId HID7 = HostId.hostId(MAC7, VLAN300);
 
     private static final ProviderId PID = new ProviderId("of", "foo");
 
     private static IdGenerator idGenerator;
 
+    private final Interface v100h1 =
+            new Interface("v100h1", CP1, null, null, VLAN100);
+    private final Interface v100h2 =
+            new Interface("v100h2", CP2, null, null, VLAN100);
+    private final Interface v200h1 =
+            new Interface("v200h1", CP3, null, null, VLAN200);
+    private final Interface v200h2 =
+            new Interface("v200h2", CP4, null, null, VLAN200);
+    private final Interface v300h1 =
+            new Interface("v300h1", CP5, null, null, VLAN300);
+    private final Interface v300h2 =
+            new Interface("v300h2", CP6, null, null, VLAN300);
+
+    private final Host v100host1 =
+            new DefaultHost(PID, HID1, MAC1, VLAN100,
+                    getLocation(1), Collections.singleton(IP1));
+    private final Host v100host2 =
+            new DefaultHost(PID, HID2, MAC2, VLAN100,
+                    getLocation(2), Sets.newHashSet());
+    private final Host v200host1 =
+            new DefaultHost(PID, HID3, MAC3, VLAN200,
+                    getLocation(3), Collections.singleton(IP2));
+    private final Host v200host2 =
+            new DefaultHost(PID, HID4, MAC4, VLAN200,
+                    getLocation(4), Sets.newHashSet());
+    private final Host v300host1 =
+            new DefaultHost(PID, HID5, MAC5, VLAN300,
+                    getLocation(5), Sets.newHashSet());
+    private final Host v300host2 =
+            new DefaultHost(PID, HID6, MAC6, VLAN300,
+                    getLocation(6), Sets.newHashSet());
+    private final Host v300host3 =
+            new DefaultHost(PID, HID7, MAC7, VLAN300,
+                    getLocation(7), Sets.newHashSet());
+
+    private final Set<Interface> avaliableInterfaces =
+            ImmutableSet.of(v100h1, v100h2, v200h1, v200h2, v300h1, v300h2);
+
+    private final Set<Host> avaliableHosts =
+            ImmutableSet.of(v100host1, v100host2, v200host1,
+                    v200host2, v300host1, v300host2, v300host3);
+
+    private ApplicationService applicationService;
+    private CoreService coreService;
+    private HostListener hostListener;
+    private NetworkConfigService configService;
+    private Set<Host> hostsAvailable;
+    private HostService hostService;
+    private IntentService intentService;
+    private InterfaceService interfaceService;
+    private VplsConfigurationService vplsConfigService;
+    private Vpls vpls;
+
     @Before
     public void setUp() throws Exception {
         idGenerator = new TestIdGenerator();
@@ -147,6 +207,8 @@
 
         applicationService = createMock(ApplicationService.class);
 
+        configService = createMock(NetworkConfigService.class);
+
         coreService = createMock(CoreService.class);
         expect(coreService.registerApplication(APP_NAME))
                 .andReturn(APPID);
@@ -165,12 +227,25 @@
         expectLastCall().anyTimes();
         addIntfConfig();
 
+        SetMultimap<String, Interface> vplsNetworks =
+                HashMultimap.create();
+        vplsNetworks.put(NET1, v100h1);
+        vplsNetworks.put(NET1, v200h1);
+        vplsNetworks.put(NET1, v300h1);
+        vplsNetworks.put(NET2, v100h2);
+        vplsNetworks.put(NET2, v200h2);
+        vplsNetworks.put(NET2, v300h2);
+
+        vplsConfigService = new TestVplsConfigService(vplsNetworks);
+
         vpls = new Vpls();
         vpls.applicationService = applicationService;
         vpls.coreService = coreService;
         vpls.hostService = hostService;
+        vpls.vplsConfigService = vplsConfigService;
         vpls.intentService = intentService;
         vpls.interfaceService = interfaceService;
+        vpls.configService = configService;
         vpls.intentSynchronizer = intentSynchronizer;
 
     }
@@ -181,181 +256,189 @@
     }
 
     /**
-     * Creates the interface configuration. On devices 1, 2 and 3 is configured
-     * an interface on port 1 with vlan 1. On devices 4, 5 and 6 is configured
-     * an interface on port 1 with vlan 2. On device 5 no interfaces are
-     * configured.
+     * Creates the interface configuration. On devices 1 and 2 is configured
+     * an interface on port 1 with vlan 100. On devices 3 and 4 is configured
+     * an interface on port 1 with vlan 200. On device 5 and 6 is configured
+     * an interface on port 1 with vlan 300.
      */
     private void addIntfConfig() {
-        Set<Interface> interfaces = Sets.newHashSet();
-        Set<Interface> vlanOneSet = Sets.newHashSet();
-        Set<Interface> vlanTwoSet = Sets.newHashSet();
+        Set<Interface> interfaces = ImmutableSet.copyOf(avaliableInterfaces);
+        Set<Interface> vlanOneSet = ImmutableSet.of(v100h1, v100h2);
+        Set<Interface> vlanTwoSet = ImmutableSet.of(v200h1, v200h2);
+        Set<Interface> vlanThreeSet = ImmutableSet.of(v300h1, v300h2);
 
-        for (int i = 1; i <= NUM_DEVICES - 1; i++) {
-            ConnectPoint cp = new ConnectPoint(getDeviceId(i), P1);
-
-            Interface intf =
-                    new Interface("intfOne", cp, Collections.emptyList(), null,
-                                  VlanId.NONE);
-
-            if (i <= 3) {
-                intf = new Interface("intfTwo", cp, Collections.emptyList(),
-                                     null, VLAN1);
-                interfaces.add(intf);
-                vlanOneSet.add(intf);
-            } else if (i > 3 && i <= 6) {
-                intf = new Interface("intfThree", cp, Collections.emptyList(),
-                                     null, VLAN2);
-                interfaces.add(intf);
-                vlanTwoSet.add(intf);
-            }
-            expect(interfaceService.getInterfacesByPort(cp))
+        avaliableInterfaces.forEach(intf -> {
+            expect(interfaceService.getInterfacesByPort(intf.connectPoint()))
                     .andReturn(Sets.newHashSet(intf)).anyTimes();
-        }
-        expect(interfaceService.getInterfacesByVlan(VLAN1))
+        });
+        expect(interfaceService.getInterfacesByVlan(VLAN100))
                 .andReturn(vlanOneSet).anyTimes();
-        expect(interfaceService.getInterfacesByVlan(VLAN2))
+        expect(interfaceService.getInterfacesByVlan(VLAN200))
                 .andReturn(vlanTwoSet).anyTimes();
+        expect(interfaceService.getInterfacesByVlan(VLAN300))
+                .andReturn(vlanThreeSet).anyTimes();
         expect(interfaceService.getInterfaces()).andReturn(interfaces).anyTimes();
 
         replay(interfaceService);
     }
 
     /**
-     * Checks the case in which six ports are configured with VLANs but no
-     * hosts are registered by the HostService. The first three ports have an
-     * interface configured on VLAN1, the other three on VLAN2. The number of
-     * intents expected is six: three for VLAN1, three for VLAN2. three sp2mp
-     * intents, three mp2sp intents.
+     * Six ports are configured with VLANs but no hosts are registered by the
+     * HostService. The first three ports have an interface configured on NET1,
+     * the other three on NET2. The number of intents expected is six: three for
+     * NET1, three for NET2. Six mp2sp intents. Checks if the number of intents
+     * submitted to the intent framework is equal to the number of intents
+     * expected and if all intents are equivalent.
      */
     @Test
     public void testActivateNoHosts() {
         vpls.activate();
 
         List<Intent> expectedIntents = Lists.newArrayList();
-        expectedIntents.addAll(generateVlanOneBrc());
-        expectedIntents.addAll(generateVlanTwoBrc());
+        Set<FilteredConnectPoint> fcPoints;
+
+        fcPoints = buildFCPoints(ImmutableSet.of(v100h1, v200h1, v300h1));
+        expectedIntents.addAll(generateVplsBrc(fcPoints, NET1));
+
+        fcPoints = buildFCPoints(ImmutableSet.of(v100h2, v200h2, v300h2));
+        expectedIntents.addAll(generateVplsBrc(fcPoints, NET2));
 
         checkIntents(expectedIntents);
     }
 
     /**
-     * Checks the case in which six ports are configured with VLANs and four
-     * hosts are registered by the HostService. The first three ports have an
-     * interface configured on VLAN1, the other three on VLAN2. The number of
-     * intents expected is twelve: six for VLAN1, six for VLAN2. six sp2mp
-     * intents, six mp2sp intents. For VLAN1 IPs are added to demonstrate it
-     * doesn't influence the number of intents created.
+     * Six ports are configured with VLANs and six hosts are registered by the
+     * HostService. The first three ports have an interface configured on NET1,
+     * the other three on NET2. The number of intents expected is twelve: six
+     * for VLAN1, six for NET2. six sp2mp intents, six mp2sp intents. For NET1
+     * IPs are added to demonstrate this doesn't influence the number of intents
+     * created. Checks if the number of intents submitted to the intent
+     * framework is equal to the number of intents expected and if all intents
+     * are equivalent.
      */
     @Test
-    public void testFourInterfacesConfiguredHostsPresent() {
-        Host h1 = new DefaultHost(PID, HID1, MAC1, VLAN1, getLocation(1),
-                                  Collections.singleton(IP1));
-        Host h2 = new DefaultHost(PID, HID2, MAC2, VLAN1, getLocation(2),
-                                  Collections.singleton(IP2));
-        Host h3 = new DefaultHost(PID, HID3, MAC3, VLAN1, getLocation(3),
-                                  Collections.EMPTY_SET);
-        Host h4 = new DefaultHost(PID, HID4, MAC4, VLAN2, getLocation(4),
-                                  Collections.EMPTY_SET);
-        Host h5 = new DefaultHost(PID, HID5, MAC5, VLAN2, getLocation(5),
-                                  Collections.EMPTY_SET);
-        Host h6 = new DefaultHost(PID, HID6, MAC6, VLAN2, getLocation(6),
-                                  Collections.EMPTY_SET);
-        hostsAvailable.addAll(Sets.newHashSet(h1, h2, h3, h4, h5, h6));
+    public void testSixInterfacesConfiguredHostsPresent() {
+        hostsAvailable.addAll(avaliableHosts);
 
         vpls.activate();
 
         List<Intent> expectedIntents = Lists.newArrayList();
-        expectedIntents.addAll(generateVlanOneBrc());
-        expectedIntents.addAll(generateVlanOneUni());
-        expectedIntents.addAll(generateVlanTwoBrc());
-        expectedIntents.addAll(generateVlanTwoUni());
+        Set<FilteredConnectPoint> fcPoints;
+        Set<Host> hosts;
+
+        fcPoints = buildFCPoints(ImmutableSet.of(v100h1, v200h1, v300h1));
+        hosts = ImmutableSet.of(v100host1, v200host1, v300host1);
+        expectedIntents.addAll(generateVplsBrc(fcPoints, NET1));
+        expectedIntents.addAll(generateVplsUni(fcPoints, hosts, NET1));
+
+        fcPoints = buildFCPoints(ImmutableSet.of(v100h2, v200h2, v300h2));
+        hosts = ImmutableSet.of(v100host2, v200host2, v300host2);
+        expectedIntents.addAll(generateVplsBrc(fcPoints, NET2));
+        expectedIntents.addAll(generateVplsUni(fcPoints, hosts, NET2));
 
         checkIntents(expectedIntents);
     }
 
     /**
-     * Checks the case in which six ports are configured with VLANs and
-     * initially no hosts are registered by the HostService. The first three
-     * ports have an interface configured on VLAN1, the other three have an
-     * interface configured on VLAN2. When the module starts up, three hosts -
-     * on device one, two and three - port 1 (both on VLAN1), are registered by
-     * the HostService and events are sent to the application. sp2mp intents
-     * are created for all interfaces configured and mp2sp intents are created
-     * only for the hosts attached.
-     * The number of intents expected is nine: six for VLAN1, three for VLAN2.
+     * Six ports are configured with VLANs and initially no hosts are registered
+     * by the HostService. The first three ports have an interface configured on
+     * NET1, the other three have an interface configured on NET2. When the
+     * module starts up, three hosts attached to device one, two and three -
+     * port 1, are registered by the HostService and events are sent to the
+     * application. sp2mp intents are created for all interfaces configured and
+     * mp2sp intents are created only for the hosts attached.
+     * The number of intents expected is nine: six for NET1, three for NET2.
      * Six sp2mp intents, three mp2sp intents. IPs are added on the first two
-     * hosts only to demonstrate it doesn't influence the number of intents
+     * hosts only to demonstrate this doesn't influence the number of intents
      * created.
-     * An additional host is added on device seven, port one to demonstrate
-     * that, even if it's on the same VLAN of other interfaces configured in
-     * the system, it doesn't let the application generate intents, since it's
-     * not connected to the interface configured.
+     * An additional host is added on device seven - port 1, to demonstrate that
+     * the application does not generate intents, even if the interface uses the
+     * same VLAN Id of the other interfaces configured for the specifc VPLS.
+     * Checks if the number of intents submitted to the intent framework is equal
+     * to the number of intents expected and if all intents are equivalent.
      */
     @Test
-    public void testFourInterfacesThreeHostEventsSameVlan() {
+    public void testSixInterfacesThreeHostEventsSameVpls() {
         vpls.activate();
 
-        Host h1 = new DefaultHost(PID, HID1, MAC1, VLAN1, getLocation(1),
-                                  Collections.singleton(IP1));
-        Host h2 = new DefaultHost(PID, HID2, MAC2, VLAN1, getLocation(2),
-                                  Collections.singleton(IP2));
-        Host h3 = new DefaultHost(PID, HID3, MAC3, VLAN1, getLocation(3),
-                                  Collections.EMPTY_SET);
-        Host h7 = new DefaultHost(PID, HID7, MAC7, VLAN1, getLocation(7),
-                                  Collections.EMPTY_SET);
-        hostsAvailable.addAll(Sets.newHashSet(h1, h2, h3, h7));
+        List<Intent> expectedIntents = Lists.newArrayList();
+        Set<FilteredConnectPoint> fcPoints;
+        Set<Host> hosts;
+
+        hostsAvailable.addAll(Sets.newHashSet(v100host1, v200host1, v300host1, v300host3));
 
         hostsAvailable.forEach(host ->
-            hostListener.event(new HostEvent(HostEvent.Type.HOST_ADDED, host)));
+                hostListener.event(new HostEvent(HostEvent.Type.HOST_ADDED, host)));
 
-        List<Intent> expectedIntents = Lists.newArrayList();
-        expectedIntents.addAll(generateVlanOneBrc());
-        expectedIntents.addAll(generateVlanOneUni());
-        expectedIntents.addAll(generateVlanTwoBrc());
+        fcPoints = buildFCPoints(ImmutableSet.of(v100h1, v200h1, v300h1));
+        hosts = ImmutableSet.of(v100host1, v200host1, v300host1);
+        expectedIntents.addAll(generateVplsBrc(fcPoints, NET1));
+        expectedIntents.addAll(generateVplsUni(fcPoints, hosts, NET1));
+
+        fcPoints = buildFCPoints(ImmutableSet.of(v100h2, v200h2, v300h2));
+        expectedIntents.addAll(generateVplsBrc(fcPoints, NET2));
 
         checkIntents(expectedIntents);
     }
 
     /**
-     * Checks the case in which six ports are configured with VLANs and
-     * initially no hosts are registered by the HostService. The first three
-     * ports have an interface configured on VLAN1, the other three have an
-     * interface configured on VLAN2. When the module starts up, two hosts -
-     * on device one and four - port 1 (VLAN 1 and VLAN 2), are registered by
-     * the HostService and events are sent to the application. sp2mp intents
-     * are created for all interfaces configured and no mp2sp intents are created
-     * at all, since the minimum number of hosts needed on the same vlan to
-     * create mp2sp intents is 2.
-     * The number of intents expected is six: three for VLAN1, three for VLAN2.
-     * six sp2mp intents, zero mp2sp intents. IPs are added on the first host
-     * only to demonstrate it doesn't influence the number of intents created.
+     * Generates a list of the expected sp2mp intents for a VPLS.
+     *
+     * @param fcPoints the filtered connect point
+     * @param name the name of the VPLS
+     * @return the list of expected sp2mp intents for the given VPLS
      */
-    @Test
-    public void testFourInterfacesTwoHostEventsDifferentVlan() {
-        vpls.activate();
+    private List<SinglePointToMultiPointIntent>
+    generateVplsBrc(Set<FilteredConnectPoint> fcPoints, String name) {
+        List<SinglePointToMultiPointIntent> intents = Lists.newArrayList();
 
-        Host h1 = new DefaultHost(PID, HID1, MAC1, VLAN1, getLocation(1),
-                                  Collections.singleton(IP1));
-        Host h4 = new DefaultHost(PID, HID4, MAC4, VLAN2, getLocation(4),
-                                  Collections.EMPTY_SET);
-        hostsAvailable.addAll(Sets.newHashSet(h1, h4));
+        fcPoints.forEach(point -> {
+            Set<FilteredConnectPoint> otherPoints =
+                    fcPoints.stream()
+                            .filter(fcp -> !fcp.equals(point))
+                            .collect(Collectors.toSet());
 
-        hostsAvailable.forEach(host -> {
-            hostListener.event(new HostEvent(HostEvent.Type.HOST_ADDED, host));
+            Key brckey = buildKey(PREFIX_BROADCAST,
+                    point.connectPoint(), name, MacAddress.BROADCAST);
+
+            intents.add(buildBrcIntent(brckey, point, otherPoints));
         });
 
-        List<Intent> expectedIntents = Lists.newArrayList();
-        expectedIntents.addAll(generateVlanOneBrc());
-        expectedIntents.addAll(generateVlanTwoBrc());
-
-        checkIntents(expectedIntents);
+        return intents;
     }
 
     /**
-     * Checks both that the number of intents in submitted in the intent
-     * framework it's equal to the number of intents expected and that all
-     * intents are equivalent.
+     * Generates a list of expected mp2sp intents for a given VPLS.
+     *
+     * @param fcPoints the filtered connect point
+     * @param hosts the hosts
+     * @param name the name of the VPLS
+     * @return the list of expected mp2sp intents for the given VPLS
+     */
+    private List<MultiPointToSinglePointIntent>
+    generateVplsUni(Set<FilteredConnectPoint> fcPoints, Set<Host> hosts, String name) {
+        List<MultiPointToSinglePointIntent> intents = Lists.newArrayList();
+
+        hosts.forEach(host -> {
+            FilteredConnectPoint hostPoint = getHostPoint(host, fcPoints);
+
+            Set<FilteredConnectPoint> otherPoints =
+                    fcPoints.stream()
+                            .filter(fcp -> !fcp.equals(hostPoint))
+                            .collect(Collectors.toSet());
+
+            Key uniKey = buildKey(PREFIX_UNICAST,
+                    host.location(), name, host.mac());
+
+            intents.add(buildUniIntent(uniKey, otherPoints, hostPoint, host));
+        });
+
+        return intents;
+    }
+
+    /**
+     * Checks if the number of intents submitted to the intent framework is equal
+     * to the number of intents expected and if all intents are equivalent.
      *
      * @param intents the list of intents expected
      */
@@ -367,8 +450,8 @@
             for (Intent intentTwo : intentService.getIntents()) {
                 if (intentOne.key().equals(intentTwo.key())) {
                     found = true;
-                    assertTrue(format("Comparing %s and %s", intentOne, intentTwo),
-                               IntentUtils.intentsAreEqual(intentOne, intentTwo));
+                    assertTrue(format(COMPARE, intentOne, intentTwo),
+                            IntentUtils.intentsAreEqual(intentOne, intentTwo));
                     break;
                 }
             }
@@ -377,190 +460,143 @@
     }
 
     /**
-     * Generates the list of the expected sp2mp intents for VLAN 1.
+     * Builds a broadcast intent.
      *
-     * @return the list of expected sp2mp intents for VLAN 1
-     */
-    private List<SinglePointToMultiPointIntent> generateVlanOneBrc() {
-        Key key = null;
-
-        List<SinglePointToMultiPointIntent> intents = Lists.newArrayList();
-
-        // Building sp2mp intent for H1 - VLAN1
-        key = Key.of((PREFIX_BROADCAST + "-" + DID1 + "-" + P1 + "-" + VLAN1),
-                     APPID);
-        intents.add(buildBrcIntent(key, C1, Sets.newHashSet(C2, C3), VLAN1));
-
-        // Building sp2mp intent for H2 - VLAN1
-        key = Key.of((PREFIX_BROADCAST + "-" + DID2 + "-" + P1 + "-" + VLAN1),
-                     APPID);
-        intents.add(buildBrcIntent(key, C2, Sets.newHashSet(C1, C3), VLAN1));
-
-        // Building sp2mp intent for H3 - VLAN1
-        key = Key.of((PREFIX_BROADCAST + "-" + DID3 + "-" + P1 + "-" + VLAN1),
-                     APPID);
-        intents.add(buildBrcIntent(key, C3, Sets.newHashSet(C1, C2), VLAN1));
-
-        return intents;
-    }
-
-    /**
-     * Generates the list of the expected mp2sp intents for VLAN 1.
-     *
-     * @return the list of expected mp2sp intents for VLAN 1
-     */
-    private List<MultiPointToSinglePointIntent> generateVlanOneUni() {
-        Key key = null;
-
-        List<MultiPointToSinglePointIntent> intents = Lists.newArrayList();
-
-        // Building mp2sp intent for H1 - VLAN1
-        key = Key.of((PREFIX_UNICAST + "-" + DID1 + "-" + P1 + "-" + VLAN1),
-                     APPID);
-        intents.add(buildUniIntent(key, Sets.newHashSet(C2, C3), C1, VLAN1, MAC1));
-
-        // Building mp2sp intent for H2 - VLAN1
-        key = Key.of((PREFIX_UNICAST + "-" + DID2 + "-" + P1 + "-" + VLAN1),
-                     APPID);
-        intents.add(buildUniIntent(key, Sets.newHashSet(C1, C3), C2, VLAN1, MAC2));
-
-        // Building mp2sp intent for H3 - VLAN1
-        key = Key.of((PREFIX_UNICAST + "-" + DID3 + "-" + P1 + "-" + VLAN1),
-                     APPID);
-        intents.add(buildUniIntent(key, Sets.newHashSet(C1, C2), C3, VLAN1, MAC3));
-
-        return intents;
-    }
-
-    /**
-     * Generates the list of the expected sp2mp intents for VLAN 2.
-     *
-     * @return the list of expected sp2mp intents for VLAN 2
-     */
-    private List<SinglePointToMultiPointIntent> generateVlanTwoBrc() {
-        Key key = null;
-
-        List<SinglePointToMultiPointIntent> intents = Lists.newArrayList();
-
-        // Building sp2mp intent for H4 - VLAN2
-        key = Key.of((PREFIX_BROADCAST + "-" + DID4 + "-" + P1 + "-" + VLAN2),
-                     APPID);
-        intents.add(buildBrcIntent(key, C4, Sets.newHashSet(C5, C6), VLAN2));
-
-        // Building sp2mp intent for H5 - VLAN2
-        key = Key.of((PREFIX_BROADCAST + "-" + DID5 + "-" + P1 + "-" + VLAN2),
-                     APPID);
-        intents.add(buildBrcIntent(key, C5, Sets.newHashSet(C4, C6), VLAN2));
-
-        // Building sp2mp intent for H6 - VLAN2
-        key = Key.of((PREFIX_BROADCAST + "-" + DID6 + "-" + P1 + "-" + VLAN2),
-                     APPID);
-        intents.add(buildBrcIntent(key, C6, Sets.newHashSet(C4, C5), VLAN2));
-
-        return intents;
-    }
-
-    /**
-     * Generates the list of the expected mp2sp intents for VLAN 2.
-     *
-     * @return the list of expected mp2sp intents for VLAN 2
-     */
-    private List<MultiPointToSinglePointIntent> generateVlanTwoUni() {
-        Key key = null;
-
-        List<MultiPointToSinglePointIntent> intents = Lists.newArrayList();
-
-        // Building mp2sp intent for H4 - VLAN2
-        key = Key.of((PREFIX_UNICAST + "-" + DID4 + "-" + P1 + "-" + VLAN2),
-                     APPID);
-        intents.add(buildUniIntent(key, Sets.newHashSet(C5, C6), C4, VLAN2, MAC4));
-
-        // Building mp2sp intent for H5 - VLAN2
-        key = Key.of((PREFIX_UNICAST + "-" + DID5 + "-" + P1 + "-" + VLAN2),
-                     APPID);
-        intents.add(buildUniIntent(key, Sets.newHashSet(C4, C6), C5, VLAN2, MAC5));
-
-        // Building mp2sp intent for H6 - VLAN2
-        key = Key.of((PREFIX_UNICAST + "-" + DID6 + "-" + P1 + "-" + VLAN2),
-                     APPID);
-        intents.add(buildUniIntent(key, Sets.newHashSet(C4, C5), C6, VLAN2, MAC6));
-
-        return intents;
-    }
-
-    /**
-     * Builds a Single Point to Multi Point intent.
-     *
-     * @param key  The intent key
-     * @param src  The source Connect Point
-     * @param dsts The destination Connect Points
-     * @return Single Point to Multi Point intent generated.
+     * @param key the key to identify the intent
+     * @param src the ingress connect point
+     * @param dsts the egress connect points
+     * @return the generated single-point to multi-point intent
      */
     private SinglePointToMultiPointIntent buildBrcIntent(Key key,
-                                                         ConnectPoint src,
-                                                         Set<ConnectPoint> dsts,
-                                                         VlanId vlanId) {
+                                                           FilteredConnectPoint src,
+                                                           Set<FilteredConnectPoint> dsts) {
         SinglePointToMultiPointIntent intent;
 
-        TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
-
         TrafficSelector selector = DefaultTrafficSelector.builder()
                 .matchEthDst(MacAddress.BROADCAST)
-                .matchVlanId(vlanId)
                 .build();
 
         intent = SinglePointToMultiPointIntent.builder()
                 .appId(APPID)
                 .key(key)
                 .selector(selector)
-                .treatment(treatment)
-                .ingressPoint(src)
-                .egressPoints(dsts)
+                .filteredIngressPoint(src)
+                .filteredEgressPoints(dsts)
                 .priority(PRIORITY_OFFSET)
                 .build();
         return intent;
     }
 
     /**
-     * Builds a Multi Point to Single Point intent.
+     * Builds a unicast intent.
      *
-     * @param key  The intent key
-     * @param srcs The source Connect Points
-     * @param dst  The destination Connect Point
-     * @return Multi Point to Single Point intent generated.
+     * @param key the key to identify the intent
+     * @param srcs the ingress connect points
+     * @param dst the egress connect point
+     * @param host the destination Host
+     * @return the generated multi-point to single-point intent
      */
     private MultiPointToSinglePointIntent buildUniIntent(Key key,
-                                                         Set<ConnectPoint> srcs,
-                                                         ConnectPoint dst,
-                                                         VlanId vlanId,
-                                                         MacAddress mac) {
-        MultiPointToSinglePointIntent intent;
+                                                           Set<FilteredConnectPoint> srcs,
+                                                           FilteredConnectPoint dst,
+                                                           Host host) {
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchEthDst(host.mac())
+                .build();
 
-        TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
-
-        TrafficSelector.Builder builder = DefaultTrafficSelector.builder()
-                .matchEthDst(mac)
-                .matchVlanId(vlanId);
-
-        TrafficSelector selector = builder.build();
-
-        intent = MultiPointToSinglePointIntent.builder()
+        return MultiPointToSinglePointIntent.builder()
                 .appId(APPID)
                 .key(key)
                 .selector(selector)
-                .treatment(treatment)
-                .ingressPoints(srcs)
-                .egressPoint(dst)
+                .filteredIngressPoints(srcs)
+                .filteredEgressPoint(dst)
                 .priority(PRIORITY_OFFSET)
                 .build();
-        return intent;
+
     }
 
     /**
-     * Returns the device ID of the ith device.
+     * Returns the filtered connect point associated to a given host.
      *
-     * @param i device to get the ID of
-     * @return the device ID
+     * @param host the target host
+     * @param fcps the filtered connected points
+     * @return the filtered connect point associated to the given host; null
+     * otherwise
+     */
+    private FilteredConnectPoint getHostPoint(Host host,
+                                              Set<FilteredConnectPoint> fcps) {
+        return fcps.stream()
+                .filter(fcp -> fcp.connectPoint().equals(host.location()))
+                .filter(fcp -> {
+                    VlanIdCriterion vlanCriterion =
+                            (VlanIdCriterion) fcp.trafficSelector().
+                                    getCriterion(Criterion.Type.VLAN_VID);
+
+                    return vlanCriterion != null &&
+                            vlanCriterion.vlanId().equals(host.vlan());
+                })
+                .findFirst()
+                .orElse(null);
+    }
+
+    /**
+     * Computes a set of filtered connect points from given interfaces.
+     *
+     * @param interfaces the interfaces belonging to the VPLS
+     * @return the set of filtered connect points
+     */
+    private Set<FilteredConnectPoint> buildFCPoints(Set<Interface> interfaces) {
+        // Build all filtered connected point in the network
+        return interfaces
+                .stream()
+                .map(intf -> {
+                    TrafficSelector.Builder selectorBuilder =
+                            DefaultTrafficSelector.builder();
+
+                    if (!intf.vlan().equals(VlanId.NONE)) {
+                        selectorBuilder.matchVlanId(intf.vlan());
+                    }
+
+                    return new FilteredConnectPoint(intf.connectPoint(),
+                            selectorBuilder.build());
+                })
+                .collect(Collectors.toSet());
+    }
+
+    /**
+     * Builds an intent Key either for a single-point to multi-point or
+     * multi-point to single-point intent, based on a prefix that defines
+     * the intent type, the connection point representing the source or the
+     * destination and the VLAN Id representing the network.
+     *
+     * @param prefix the key prefix
+     * @param cPoint the ingress/egress connect point
+     * @param networkName the VPLS name
+     * @param hostMac the ingress/egress MAC address
+     * @return the key to identify the intent
+     */
+    private Key buildKey(String prefix,
+                           ConnectPoint cPoint,
+                           String networkName,
+                           MacAddress hostMac) {
+        String keyString = networkName +
+                DASH +
+                prefix +
+                DASH +
+                cPoint.deviceId() +
+                DASH +
+                cPoint.port() +
+                DASH +
+                hostMac;
+
+        return Key.of(keyString, APPID);
+    }
+
+    /**
+     * Returns the device Id of the ith device.
+     *
+     * @param i the device to get the Id of
+     * @return the device Id
      */
     private static DeviceId getDeviceId(int i) {
         return DeviceId.deviceId("" + i);
@@ -571,8 +607,8 @@
     }
 
     /**
-     * Represents a fake IntentService class that easily allows to store and
-     * retrieve intents without implementing the IntentService logic.
+     * Represents a fake IntentService class that allows to store and retrieve
+     * intents without implementing the IntentService logic.
      */
     private class TestIntentService extends IntentServiceAdapter {
 
@@ -628,13 +664,15 @@
         @Override
         public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
             return hosts.stream()
-                    .filter(h -> h.location().elementId().equals(connectPoint.elementId())
-                              && h.location().port().equals(connectPoint.port()))
+                    .filter(h -> h.location().equals(connectPoint))
                     .collect(Collectors.toSet());
         }
 
     }
 
+    /**
+     * Represents a fake IdGenerator class for intents.
+     */
     private static class TestIdGenerator implements IdGenerator {
 
         private final AtomicLong id = new AtomicLong(0);
@@ -656,7 +694,7 @@
         private final IntentService intentService;
 
         /**
-         * Creates a new test intent synchronizer.
+         * Creates a new intent test synchronizer.
          *
          * @param intentService intent service
          */
@@ -687,4 +725,120 @@
         }
     }
 
+    /**
+     * Represents a fake VplsConfigService class which is needed for testing.
+     */
+    private class TestVplsConfigService implements VplsConfigurationService {
+
+        private final SetMultimap<String, Interface> vplsNetworks;
+        private Set<String> vplsAffectByApi = new HashSet<>();
+
+        TestVplsConfigService(SetMultimap<String, Interface> vplsNetworks) {
+            this.vplsNetworks = vplsNetworks;
+        }
+
+        @Override
+        public void addVpls(String name, Set<String> ifaces) {
+            if (!vplsNetworks.containsKey(name)) {
+                ifaces.forEach(iface -> {
+                    avaliableInterfaces.forEach(intf -> {
+                        if (intf.name().equals(iface)) {
+                            vplsNetworks.put(name, intf);
+                        }
+                    });
+                });
+            }
+        }
+
+        @Override
+        public void removeVpls(String name) {
+            if (vplsNetworks.containsKey(name)) {
+                vplsNetworks.removeAll(name);
+            }
+        }
+
+        @Override
+        public void addInterfaceToVpls(String name, String iface) {
+            if (!vplsNetworks.containsKey(name)) {
+                avaliableInterfaces.forEach(intf -> {
+                    if (intf.name().equals(iface)) {
+                        vplsNetworks.put(name, intf);
+                    }
+                });
+            }
+        }
+
+        @Override
+        public void removeInterfaceFromVpls(String iface) {
+            SetMultimap<String, Interface> search = HashMultimap.create(vplsNetworks);
+            search.entries().forEach(e -> {
+                if (e.getValue().name().equals(iface)) {
+                    vplsNetworks.remove(e.getKey(), iface);
+                }
+            });
+        }
+
+        @Override
+        public void cleanVpls() {
+            vplsNetworks.clear();
+        }
+
+        @Override
+        public Set<String> getVplsAffectedByApi() {
+            Set<String> vplsNames = ImmutableSet.copyOf(vplsAffectByApi);
+
+            vplsAffectByApi.clear();
+
+            return vplsNames;
+        }
+
+        @Override
+        public Set<Interface> getAllInterfaces() {
+            return vplsNetworks.values()
+                    .stream()
+                    .collect(Collectors.toSet());
+        }
+
+        @Override
+        public Set<Interface> getVplsInterfaces(String name) {
+            return vplsNetworks.get(name)
+                    .stream()
+                    .collect(Collectors.toSet());
+        }
+
+        @Override
+        public Set<String> getAllVpls() {
+            return vplsNetworks.keySet();
+        }
+
+        @Override
+        public Set<String> getOldVpls() {
+            return vplsNetworks.keySet();
+        }
+
+        @Override
+        public SetMultimap<String, Interface> getVplsNetworks() {
+            return ImmutableSetMultimap.copyOf(vplsNetworks);
+        }
+
+        @Override
+        public SetMultimap<String, Interface> getVplsNetwork(VlanId vlan,
+                                                             ConnectPoint connectPoint) {
+            String vplsNetworkName =
+                    vplsNetworks.entries().stream()
+                            .filter(e -> e.getValue().connectPoint().equals(connectPoint))
+                            .filter(e -> e.getValue().vlan().equals(vlan))
+                            .map(e -> e.getKey())
+                            .findFirst()
+                            .orElse(null);
+            SetMultimap<String, Interface> result = HashMultimap.create();
+            if (vplsNetworkName != null && vplsNetworks.containsKey(vplsNetworkName)) {
+                vplsNetworks.get(vplsNetworkName)
+                        .forEach(intf -> result.put(vplsNetworkName, intf));
+                return result;
+            }
+            return null;
+        }
+
+    }
 }
diff --git a/apps/vpls/src/test/java/org/onosproject/vpls/config/VplsConfigTest.java b/apps/vpls/src/test/java/org/onosproject/vpls/config/VplsConfigTest.java
new file mode 100644
index 0000000..6ef0284
--- /dev/null
+++ b/apps/vpls/src/test/java/org/onosproject/vpls/config/VplsConfigTest.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vpls.config;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.TestApplicationId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.config.Config;
+import org.onosproject.net.config.ConfigApplyDelegate;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests for the {@link VplsConfig} class.
+ */
+public class VplsConfigTest {
+    private static final String APP_NAME = "org.onosproject.vpls";
+    private static final ApplicationId APP_ID = new TestApplicationId(APP_NAME);
+    private static final String VPLS = "vplsNetworks";
+    private static final String NAME = "name";
+    private static final String INTERFACE = "interfaces";
+    private static final String NET1 = "net1";
+    private static final String NET2 = "net2";
+    private static final String NEWNET = "newnet";
+
+    private static final String IF1 = "sw5-4-100";
+    private static final String IF2 = "sw5-4-200";
+    private static final String IF3 = "sw5-5-100";
+    private static final String IF4 = "sw6-5-100";
+    private static final String IF5 = "sw6-5-400";
+    private static final String IF_NON_EXIST = "sw7-5-100";
+
+    private static final String JSON_TREE = "{\"" + VPLS +
+            "\" : [{\"" + NAME + "\" : \"net1\"," +
+            "\"" + INTERFACE + "\" : [" +
+            "\"sw5-4-100\",\"sw5-4-200\",\"sw5-5-100\"]}]}";
+    private static final String EMPTY_JSON_TREE = "{}";
+
+    private final ObjectMapper mapper = new ObjectMapper();
+    private final ConfigApplyDelegate delegate = new MockCfgDelegate();
+    private final VplsNetworkConfig initialNetwork = createInitialNetwork();
+
+    private Set<VplsNetworkConfig> networks = new HashSet<>();
+    private VplsConfig vplsConfig = new VplsConfig();
+    private VplsConfig emptyVplsConfig = new VplsConfig();
+
+    @Before
+    public void setUp() throws Exception {
+        JsonNode tree = new ObjectMapper().readTree(JSON_TREE);
+        vplsConfig.init(APP_ID, APP_NAME, tree, mapper, delegate);
+        JsonNode emptyTree = new ObjectMapper().readTree(EMPTY_JSON_TREE);
+        emptyVplsConfig.init(APP_ID, APP_NAME, emptyTree, mapper, delegate);
+        networks.add(initialNetwork);
+    }
+
+    /**
+     * Tests if a VPLS configuration can be retrieved from JSON.
+     */
+    @Test
+    public void testVplsNetworks() {
+        assertEquals(networks, vplsConfig.vplsNetworks());
+    }
+
+    /**
+     * Tests an empty VPLS application configuration is retrieved from JSON.
+     */
+    @Test
+    public void testEmptyVplsNetworks() {
+        assertTrue(emptyVplsConfig.vplsNetworks().isEmpty());
+    }
+
+    /**
+     * Tests if a VPLS can be found by name.
+     */
+    @Test
+    public void testGetVplsWithName() {
+        assertNotNull(vplsConfig.getVplsWithName(NET1));
+        assertNull(vplsConfig.getVplsWithName(NET2));
+    }
+
+    /**
+     * Tests the addition of a new VPLS.
+     */
+    @Test
+    public void testAddNetwork() {
+        int initialSize = vplsConfig.vplsNetworks().size();
+        VplsNetworkConfig newNetwork = createNewNetwork();
+        vplsConfig.addVpls(newNetwork);
+        assertEquals(initialSize + 1, vplsConfig.vplsNetworks().size());
+        networks.add(newNetwork);
+        assertEquals(networks, vplsConfig.vplsNetworks());
+    }
+
+    /**
+     * Tests the addition of new VPLS to an empty configuration.
+     */
+    @Test
+    public void testAddNetworkToEmpty() {
+        VplsNetworkConfig newNetwork = createNewNetwork();
+        emptyVplsConfig.addVpls(newNetwork);
+
+        assertFalse(emptyVplsConfig.vplsNetworks().isEmpty());
+    }
+
+    /**
+     * Tests the removal of an existing VPLS from the configuration.
+     */
+    @Test
+    public void testRemoveExistingNetwork() {
+        int initialSize = vplsConfig.vplsNetworks().size();
+        vplsConfig.removeVpls(NET1);
+
+        assertEquals(initialSize - 1, vplsConfig.vplsNetworks().size());
+    }
+
+    /**
+     * Tests the removal of a non-existing VPLS from the configuration.
+     */
+    @Test
+    public void testRemoveInexistingNetwork() {
+        int initialSize = vplsConfig.vplsNetworks().size();
+        vplsConfig.removeVpls(NET2);
+
+        assertEquals(initialSize, vplsConfig.vplsNetworks().size());
+    }
+
+    /**
+     * Tests the addition of a new interface.
+     */
+    @Test
+    public void testAddInterfaceToNetwork() {
+        int initialSize = vplsConfig.getVplsWithName(NET1).ifaces().size();
+        vplsConfig.addInterfaceToVpls(NET1, IF4);
+
+        assertEquals(initialSize + 1, vplsConfig.getVplsWithName(NET1).ifaces().size());
+    }
+
+    /**
+     * Tests the addition of a new interface when it already exists.
+     */
+    @Test
+    public void testAddExistingInterfaceToNetwork() {
+        int initialSize = vplsConfig.getVplsWithName(NET1).ifaces().size();
+        vplsConfig.addInterfaceToVpls(NET1, IF1);
+
+        assertEquals(initialSize, vplsConfig.getVplsWithName(NET1).ifaces().size());
+    }
+
+    /**
+     * Tests the retrieval of a VPLS, given an interface name.
+     */
+    @Test
+    public void testgetNetworkFromInterface() {
+        assertNotNull(vplsConfig.getVplsFromInterface(IF1));
+        assertNull(vplsConfig.getVplsFromInterface(IF_NON_EXIST));
+    }
+
+    /**
+     * Tests the removal of an interface.
+     */
+    @Test
+    public void testRemoveExistingInterfaceFromNetwork() {
+        int initialSize = vplsConfig.getVplsWithName(NET1).ifaces().size();
+        vplsConfig.removeInterfaceFromVpls(initialNetwork, IF1);
+
+        assertEquals(initialSize - 1, vplsConfig.getVplsWithName(NET1).ifaces().size());
+    }
+
+    /**
+     * Tests the removal of an interface from a VPLS when it does not exist.
+     */
+    @Test
+    public void testRemoveNonExistingInterfaceFromNetwork() {
+        int initialSize = vplsConfig.getVplsWithName(NET1).ifaces().size();
+        vplsConfig.removeInterfaceFromVpls(initialNetwork, IF_NON_EXIST);
+
+        assertEquals(initialSize, vplsConfig.getVplsWithName(NET1).ifaces().size());
+    }
+
+    /**
+     * Tests if the two interfaces are attached to the network
+     * while one of the interface is attached and another one is not.
+     */
+    @Test
+    public void testIsAttached() {
+        VplsNetworkConfig network = createNewNetwork();
+
+        assertTrue(network.isAttached(IF4));
+        assertFalse(network.isAttached(IF_NON_EXIST));
+    }
+
+    private class MockCfgDelegate implements ConfigApplyDelegate {
+
+        @Override
+        public void onApply(@SuppressWarnings("rawtypes") Config config) {
+            config.apply();
+        }
+
+    }
+
+    private VplsNetworkConfig createInitialNetwork() {
+        Set<String> ifaces = new HashSet<>(Arrays.asList(IF1, IF2, IF3));
+
+        return new VplsNetworkConfig(NET1, ifaces);
+    }
+
+    private VplsNetworkConfig createNewNetwork() {
+        Set<String> ifaces = new HashSet<>(Arrays.asList(IF4, IF5));
+
+        return new VplsNetworkConfig(NEWNET, ifaces);
+    }
+}
