diff --git a/apps/castor/src/main/java/org/onosproject/castor/ConnectivityManager.java b/apps/castor/src/main/java/org/onosproject/castor/ConnectivityManager.java
new file mode 100644
index 0000000..bd55d0d
--- /dev/null
+++ b/apps/castor/src/main/java/org/onosproject/castor/ConnectivityManager.java
@@ -0,0 +1,478 @@
+/*
+ * 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.castor;
+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.Ethernet;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.IPv6;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.TpPort;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.net.ConnectPoint;
+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.Key;
+import org.onosproject.net.intent.MultiPointToSinglePointIntent;
+import org.onosproject.net.intent.PointToPointIntent;
+import org.onosproject.routing.IntentSynchronizationService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Manages the connectivity requirements between peers.
+ */
+@Component(immediate = true, enabled = true)
+@Service
+public class ConnectivityManager implements ConnectivityManagerService {
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected IntentSynchronizationService intentSynchronizer;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CastorStore castorStore;
+
+    private static final int PRIORITY_OFFSET = 1000;
+    private static final int FLOW_PRIORITY = 500;
+    private static final String SUFFIX_DST = "dst";
+    private static final String SUFFIX_SRC = "src";
+    private static final String SUFFIX_ICMP = "icmp";
+
+    private static final Logger log = LoggerFactory.getLogger(ConnectivityManager.class);
+
+    private static final short BGP_PORT = 179;
+
+    private ApplicationId appId;
+
+    @Activate
+    public void activate() {
+        appId = coreService.getAppId(Castor.CASTOR_APP);
+    }
+
+    @Deactivate
+    public void deactivate() {
+    }
+
+    /**
+     * Inputs the Route Servers.
+     */
+    @Override
+    public void start(Peer server) {
+        //routeServers.add(server);
+        //allPeers.add(server);
+        castorStore.storePeer(server);
+        castorStore.storeServer(server);
+    }
+
+    /**
+     * Stops the peer connectivity manager.
+     */
+    public void stop() {};
+
+    /**
+     * Sets up paths to establish connectivity between all internal.
+     * BGP speakers and external BGP peers.
+     */
+    @Override
+    public void setUpConnectivity(Peer peer) {
+
+        if (!castorStore.getCustomers().contains(peer)) {
+            castorStore.storePeer(peer);
+            castorStore.storeCustomer(peer);
+        }
+
+        for (Peer routeServer : castorStore.getServers()) {
+            log.debug("Start to set up BGP paths for BGP peer and Route Server"
+                    + peer + "&" + routeServer);
+
+            buildSpeakerIntents(routeServer, peer).forEach(i -> {
+                    castorStore.storePeerIntent(i.key(), i);
+                    intentSynchronizer.submit(i);
+                });
+        }
+    }
+
+    private Collection<PointToPointIntent> buildSpeakerIntents(Peer speaker, Peer peer) {
+        List<PointToPointIntent> intents = new ArrayList<>();
+
+        IpAddress peerAddress = IpAddress.valueOf(peer.getIpAddress());
+        IpAddress speakerAddress = IpAddress.valueOf(speaker.getIpAddress());
+
+        checkNotNull(peerAddress);
+
+        intents.addAll(buildIntents(ConnectPoint.deviceConnectPoint(speaker.getPort()), speakerAddress,
+                ConnectPoint.deviceConnectPoint(peer.getPort()), peerAddress));
+
+        return intents;
+    }
+
+    /**
+     * Builds the required intents between the two pairs of connect points and
+     * IP addresses.
+     *
+     * @param portOne the first connect point
+     * @param ipOne the first IP address
+     * @param portTwo the second connect point
+     * @param ipTwo the second IP address
+     * @return the intents to install
+     */
+    private Collection<PointToPointIntent> buildIntents(ConnectPoint portOne,
+                                                        IpAddress ipOne,
+                                                        ConnectPoint portTwo,
+                                                        IpAddress ipTwo) {
+
+        List<PointToPointIntent> intents = new ArrayList<>();
+
+        TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
+        TrafficSelector selector;
+        Key key;
+
+        byte tcpProtocol;
+        byte icmpProtocol;
+
+        if (ipOne.isIp4()) {
+            tcpProtocol = IPv4.PROTOCOL_TCP;
+            icmpProtocol = IPv4.PROTOCOL_ICMP;
+        } else {
+            tcpProtocol = IPv6.PROTOCOL_TCP;
+            icmpProtocol = IPv6.PROTOCOL_ICMP6;
+        }
+
+        // Path from BGP speaker to BGP peer matching source TCP port 179
+        selector = buildSelector(tcpProtocol,
+                ipOne,
+                ipTwo,
+                BGP_PORT,
+                null);
+
+        key = buildKey(ipOne, ipTwo, SUFFIX_SRC);
+
+        intents.add(PointToPointIntent.builder()
+                .appId(appId)
+                .key(key)
+                .selector(selector)
+                .treatment(treatment)
+                .ingressPoint(portOne)
+                .egressPoint(portTwo)
+                .priority(PRIORITY_OFFSET)
+                .build());
+
+        // Path from BGP peer to BGP speaker matching destination TCP port 179
+        selector = buildSelector(tcpProtocol,
+                ipTwo,
+                ipOne,
+                null,
+                BGP_PORT);
+
+        key = buildKey(ipTwo, ipOne, SUFFIX_DST);
+
+        intents.add(PointToPointIntent.builder()
+                .appId(appId)
+                .key(key)
+                .selector(selector)
+                .treatment(treatment)
+                .ingressPoint(portTwo)
+                .egressPoint(portOne)
+                .priority(PRIORITY_OFFSET)
+                .build());
+
+        // ICMP path from BGP speaker to BGP peer
+        selector = buildSelector(icmpProtocol,
+                ipOne,
+                ipTwo,
+                null,
+                null);
+
+        key = buildKey(ipOne, ipTwo, SUFFIX_ICMP);
+
+        intents.add(PointToPointIntent.builder()
+                .appId(appId)
+                .key(key)
+                .selector(selector)
+                .treatment(treatment)
+                .ingressPoint(portOne)
+                .egressPoint(portTwo)
+                .priority(PRIORITY_OFFSET)
+                .build());
+
+        // ICMP path from BGP peer to BGP speaker
+        selector = buildSelector(icmpProtocol,
+                ipTwo,
+                ipOne,
+                null,
+                null);
+
+        key = buildKey(ipTwo, ipOne, SUFFIX_ICMP);
+
+        intents.add(PointToPointIntent.builder()
+                .appId(appId)
+                .key(key)
+                .selector(selector)
+                .treatment(treatment)
+                .ingressPoint(portTwo)
+                .egressPoint(portOne)
+                .priority(PRIORITY_OFFSET)
+                .build());
+
+        return intents;
+    }
+
+    /**
+     * Builds a traffic selector based on the set of input parameters.
+     *
+     * @param ipProto IP protocol
+     * @param srcIp source IP address
+     * @param dstIp destination IP address
+     * @param srcTcpPort source TCP port, or null if shouldn't be set
+     * @param dstTcpPort destination TCP port, or null if shouldn't be set
+     * @return the new traffic selector
+     */
+    private TrafficSelector buildSelector(byte ipProto, IpAddress srcIp,
+                                          IpAddress dstIp, Short srcTcpPort,
+                                          Short dstTcpPort) {
+        TrafficSelector.Builder builder = DefaultTrafficSelector.builder().matchIPProtocol(ipProto);
+
+        if (dstIp.isIp4()) {
+            builder.matchEthType(Ethernet.TYPE_IPV4)
+                    .matchIPSrc(IpPrefix.valueOf(srcIp, IpPrefix.MAX_INET_MASK_LENGTH))
+                    .matchIPDst(IpPrefix.valueOf(dstIp, IpPrefix.MAX_INET_MASK_LENGTH));
+        } else {
+            builder.matchEthType(Ethernet.TYPE_IPV6)
+                    .matchIPv6Src(IpPrefix.valueOf(srcIp, IpPrefix.MAX_INET6_MASK_LENGTH))
+                    .matchIPv6Dst(IpPrefix.valueOf(dstIp, IpPrefix.MAX_INET6_MASK_LENGTH));
+        }
+
+        if (srcTcpPort != null) {
+            builder.matchTcpSrc(TpPort.tpPort(srcTcpPort));
+        }
+
+        if (dstTcpPort != null) {
+            builder.matchTcpDst(TpPort.tpPort(dstTcpPort));
+        }
+
+        return builder.build();
+    }
+
+    /**
+     * Builds an intent Key for a point-to-point intent based off the source
+     * and destination IP address, as well as a suffix String to distinguish
+     * between different types of intents between the same source and
+     * destination.
+     *
+     * @param srcIp source IP address
+     * @param dstIp destination IP address
+     * @param suffix suffix string
+     * @return intent key
+     */
+    private Key buildKey(IpAddress srcIp, IpAddress dstIp, String suffix) {
+        String keyString = new StringBuilder()
+                .append(srcIp.toString())
+                .append("-")
+                .append(dstIp.toString())
+                .append("-")
+                .append(suffix)
+                .toString();
+
+        return Key.of(keyString, appId);
+    }
+
+    @Override
+    public void setUpL2(Peer peer) {
+
+        // First update all the previous existing intents. Update ingress points.
+
+        if (!castorStore.getLayer2Intents().isEmpty()) {
+            updateExistingL2Intents(peer);
+        }
+
+        Set<ConnectPoint> ingressPorts = new HashSet<>();
+        ConnectPoint egressPort = ConnectPoint.deviceConnectPoint(peer.getPort());
+
+        for (Peer inPeer : castorStore.getAllPeers()) {
+            if (!inPeer.getName().equals(peer.getName())) {
+                ingressPorts.add(ConnectPoint.deviceConnectPoint(inPeer.getPort()));
+            }
+        }
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        MacAddress macAddress = castorStore.getAddressMap().get(IpAddress.valueOf(peer.getIpAddress()));
+        selector.matchEthDst(macAddress);
+        TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
+        Key key = Key.of(peer.getIpAddress(), appId);
+
+        MultiPointToSinglePointIntent intent = MultiPointToSinglePointIntent.builder()
+                .appId(appId)
+                .key(key)
+                .selector(selector.build())
+                .treatment(treatment)
+                .ingressPoints(ingressPorts)
+                .egressPoint(egressPort)
+                .priority(FLOW_PRIORITY)
+                .build();
+        intentSynchronizer.submit(intent);
+        castorStore.storeLayer2Intent(peer.getIpAddress(), intent);
+        castorStore.removeCustomer(peer);
+        peer.setL2(true);
+        castorStore.storeCustomer(peer);
+    }
+
+    /**
+     * Updates the existing layer 2 flows. Whenever a new Peer is added, it is also
+     * added as the ingress point to the existing layer two flows.
+     *
+     * @param peer The Peer being added.
+     */
+    private void updateExistingL2Intents(Peer peer) {
+
+        Collection<MultiPointToSinglePointIntent> oldIntents = castorStore.getLayer2Intents().values();
+
+        for (MultiPointToSinglePointIntent oldIntent : oldIntents) {
+
+            Set<ConnectPoint> ingressPoints = oldIntent.ingressPoints();
+            ConnectPoint egressPoint = oldIntent.egressPoint();
+            if (ingressPoints.add(ConnectPoint.deviceConnectPoint(peer.getPort()))) {
+
+                MultiPointToSinglePointIntent updatedMp2pIntent =
+                        MultiPointToSinglePointIntent.builder()
+                                .appId(appId)
+                                .key(oldIntent.key())
+                                .selector(oldIntent.selector())
+                                .treatment(oldIntent.treatment())
+                                .ingressPoints(ingressPoints)
+                                .egressPoint(egressPoint)
+                                .priority(oldIntent.priority())
+                                .build();
+
+                //layer2Intents.put(peer.getIpAddress(), updatedMp2pIntent);
+                castorStore.storeLayer2Intent(peer.getIpAddress(), updatedMp2pIntent);
+                intentSynchronizer.submit(updatedMp2pIntent);
+            }
+        }
+    }
+
+    @Override
+    public void deletePeer(Peer peer) {
+
+        if (castorStore.getCustomers().contains(peer)) {
+
+            deletel3(peer);
+
+            for (Peer customer : castorStore.getCustomers()) {
+                if (customer.getIpAddress().equals(peer.getIpAddress()) && customer.getl2Status()) {
+                    deleteL2(customer);
+                    updateL2AfterDeletion(customer);
+                }
+            }
+            castorStore.removeCustomer(peer);
+        }
+    }
+
+    /**
+     * Delete all the flows between the Peer being deleted and the Route Servers
+     * to kill the BGP sessions. It uses the keys to retrive the previous intents
+     * and withdraw them.
+     *
+     * @param peer The Peer being deleted.
+     */
+    private void deletel3(Peer peer) {
+
+        List<Key> keys = new LinkedList<>();
+        IpAddress ipTwo = IpAddress.valueOf(peer.getIpAddress());
+
+        for (Peer server : castorStore.getServers()) {
+            IpAddress ipOne = IpAddress.valueOf(server.getIpAddress());
+            keys.add(buildKey(ipOne, ipTwo, SUFFIX_SRC));
+            keys.add(buildKey(ipTwo, ipOne, SUFFIX_DST));
+            keys.add(buildKey(ipOne, ipTwo, SUFFIX_ICMP));
+            keys.add(buildKey(ipTwo, ipOne, SUFFIX_ICMP));
+        }
+        for (Key keyDel : keys) {
+
+            PointToPointIntent intent = castorStore.getPeerIntents().get(keyDel);
+            intentSynchronizer.withdraw(intent);
+            castorStore.removePeerIntent(keyDel);
+        }
+    }
+
+    /**
+     * Deletes the layer two flows for the peer being deleted.
+     *
+     * @param peer The Peer being deleted.
+     */
+    private void deleteL2(Peer peer) {
+        intentSynchronizer.withdraw(castorStore.getLayer2Intents().get(peer.getIpAddress()));
+        castorStore.removeLayer2Intent(peer.getIpAddress());
+    }
+
+    /**
+     * Updates all the layer 2 flows after successful deletion of a Peer.
+     * The Peer being deleted is removed from the ingress points of all
+     * other flows.
+     *
+     * @param peer The Peer being deleted.
+     */
+    private void updateL2AfterDeletion(Peer peer) {
+        Collection<MultiPointToSinglePointIntent> oldIntents = castorStore.getLayer2Intents().values();
+        Map<String, MultiPointToSinglePointIntent> intents = new HashMap<>();
+
+        for (MultiPointToSinglePointIntent oldIntent : oldIntents) {
+
+            Set<ConnectPoint> ingressPoints = oldIntent.ingressPoints();
+            ConnectPoint egressPoint = oldIntent.egressPoint();
+            if (ingressPoints.remove(ConnectPoint.deviceConnectPoint(peer.getPort()))) {
+
+                MultiPointToSinglePointIntent updatedMp2pIntent =
+                        MultiPointToSinglePointIntent.builder()
+                                .appId(appId)
+                                .key(oldIntent.key())
+                                .selector(oldIntent.selector())
+                                .treatment(oldIntent.treatment())
+                                .ingressPoints(ingressPoints)
+                                .egressPoint(egressPoint)
+                                .priority(oldIntent.priority())
+                                .build();
+
+                intents.put(peer.getIpAddress(), updatedMp2pIntent);
+                intentSynchronizer.submit(updatedMp2pIntent);
+            }
+        }
+        for (String key : intents.keySet()) {
+            castorStore.storeLayer2Intent(key, intents.get(key));
+        }
+    }
+}
