diff --git a/apps/bgprouter/src/main/java/org/onosproject/bgprouter/BgpRouter.java b/apps/bgprouter/src/main/java/org/onosproject/bgprouter/BgpRouter.java
new file mode 100644
index 0000000..22389c3
--- /dev/null
+++ b/apps/bgprouter/src/main/java/org/onosproject/bgprouter/BgpRouter.java
@@ -0,0 +1,227 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.bgprouter;
+
+import com.google.common.collect.ConcurrentHashMultiset;
+import com.google.common.collect.Multiset;
+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.onlab.packet.Ethernet;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.flow.DefaultFlowRule;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.group.DefaultGroupBucket;
+import org.onosproject.net.group.DefaultGroupDescription;
+import org.onosproject.net.group.Group;
+import org.onosproject.net.group.GroupBucket;
+import org.onosproject.net.group.GroupBuckets;
+import org.onosproject.net.group.GroupDescription;
+import org.onosproject.net.group.GroupKey;
+import org.onosproject.net.group.GroupService;
+import org.onosproject.net.packet.PacketService;
+import org.onosproject.routingapi.FibListener;
+import org.onosproject.routingapi.FibUpdate;
+import org.onosproject.routingapi.RoutingService;
+import org.onosproject.routingapi.config.Interface;
+import org.onosproject.routingapi.config.RoutingConfigurationService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * BgpRouter component.
+ */
+@Component(immediate = true)
+public class BgpRouter {
+
+    private static final Logger log = LoggerFactory.getLogger(BgpRouter.class);
+
+    private static final String BGP_ROUTER_APP = "org.onosproject.bgprouter";
+
+    private static final int PRIORITY = 1;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected FlowRuleService flowService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected GroupService groupService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected RoutingService routingService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected RoutingConfigurationService configService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected PacketService packetService;
+
+    private ApplicationId appId;
+
+    private final Multiset<NextHop> nextHops = ConcurrentHashMultiset.create();
+    private final Map<NextHop, NextHopGroupKey> groups = new HashMap<>();
+
+    private DeviceId deviceId = DeviceId.deviceId("of:00000000000000a1"); // TODO config
+
+    private TunnellingConnectivityManager connectivityManager;
+
+    @Activate
+    protected void activate() {
+        log.info("Bgp1Router started");
+        appId = coreService.registerApplication(BGP_ROUTER_APP);
+
+        connectivityManager = new TunnellingConnectivityManager(appId,
+                                                                configService,
+                                                                packetService);
+
+        routingService.start(new InternalFibListener());
+
+        connectivityManager.start();
+
+        log.info("BgpRouter started");
+    }
+
+    @Deactivate
+    protected void deactivate() {
+        routingService.stop();
+        connectivityManager.stop();
+
+        log.info("BgpRouter stopped");
+    }
+
+    private void updateFibEntry(Collection<FibUpdate> updates) {
+        for (FibUpdate update : updates) {
+            NextHop nextHop = new NextHop(update.entry().nextHopIp(),
+                                          update.entry().nextHopMac());
+
+            addNextHop(nextHop);
+
+            TrafficSelector selector = DefaultTrafficSelector.builder()
+                    .matchEthType(Ethernet.TYPE_IPV4)
+                    .matchIPDst(update.entry().prefix())
+                    .build();
+
+            // TODO ensure group exists
+            NextHopGroupKey groupKey = groups.get(nextHop);
+            Group group = groupService.getGroup(deviceId, groupKey);
+            if (group == null) {
+                // TODO handle this
+                log.warn("oops, group {} wasn't there");
+                continue;
+            }
+
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                    .group(group.id())
+                    .build();
+
+            FlowRule flowRule = new DefaultFlowRule(deviceId, selector, treatment,
+                                                    PRIORITY, appId, 0, true,
+                                                    FlowRule.Type.IP);
+
+            flowService.applyFlowRules(flowRule);
+        }
+    }
+
+    private void deleteFibEntry(Collection<FibUpdate> withdraws) {
+        for (FibUpdate update : withdraws) {
+            NextHop nextHop = new NextHop(update.entry().nextHopIp(),
+                                          update.entry().nextHopMac());
+
+            deleteNextHop(nextHop);
+
+            TrafficSelector selector = DefaultTrafficSelector.builder()
+                    .matchIPDst(update.entry().prefix())
+                    .build();
+
+            FlowRule flowRule = new DefaultFlowRule(deviceId, selector, null,
+                                                    PRIORITY, appId, 0, true,
+                                                    FlowRule.Type.IP);
+
+            flowService.removeFlowRules(flowRule);
+        }
+    }
+
+    private void addNextHop(NextHop nextHop) {
+        if (nextHops.add(nextHop, 1) == 0) {
+            // There was no next hop in the multiset
+
+            Interface egressIntf = configService.getMatchingInterface(nextHop.ip());
+            if (egressIntf == null) {
+                log.warn("no egress interface found for {}", nextHop);
+                return;
+            }
+
+            NextHopGroupKey groupKey = new NextHopGroupKey(nextHop.ip());
+            groups.put(nextHop, groupKey);
+
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                    .setEthSrc(egressIntf.mac())
+                    .setEthDst(nextHop.mac())
+                    .setVlanId(egressIntf.vlan())
+                    .setOutput(egressIntf.connectPoint().port())
+                    .build();
+
+            GroupBucket bucket = DefaultGroupBucket.createIndirectGroupBucket(treatment);
+
+            GroupDescription groupDescription
+                    = new DefaultGroupDescription(deviceId,
+                                                  GroupDescription.Type.INDIRECT,
+                                                  new GroupBuckets(Collections
+                                                                           .singletonList(bucket)),
+                                                  groupKey,
+                                                  appId);
+
+            groupService.addGroup(groupDescription);
+        }
+    }
+
+    private void deleteNextHop(NextHop nextHop) {
+        if (nextHops.remove(nextHop, 1) <= 1) {
+            // There was one or less next hops, so there are now none
+
+            log.debug("removing group");
+
+            GroupKey groupKey = groups.remove(nextHop);
+            groupService.removeGroup(deviceId, groupKey, appId);
+        }
+    }
+
+    private class InternalFibListener implements FibListener {
+
+        @Override
+        public void update(Collection<FibUpdate> updates,
+                           Collection<FibUpdate> withdraws) {
+            BgpRouter.this.deleteFibEntry(withdraws);
+            BgpRouter.this.updateFibEntry(updates);
+        }
+    }
+}
diff --git a/apps/bgprouter/src/main/java/org/onosproject/bgprouter/NextHop.java b/apps/bgprouter/src/main/java/org/onosproject/bgprouter/NextHop.java
new file mode 100644
index 0000000..9e39c45
--- /dev/null
+++ b/apps/bgprouter/src/main/java/org/onosproject/bgprouter/NextHop.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.bgprouter;
+
+import com.google.common.base.MoreObjects;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+
+import java.util.Objects;
+
+/**
+ * Created by jono on 2/12/15.
+ */
+public class NextHop {
+
+    private final IpAddress ip;
+    private final MacAddress mac;
+
+    public NextHop(IpAddress ip, MacAddress mac) {
+        this.ip = ip;
+        this.mac = mac;
+    }
+
+    public IpAddress ip() {
+        return ip;
+    }
+
+    public MacAddress mac() {
+        return mac;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof NextHop)) {
+            return false;
+        }
+
+        NextHop that = (NextHop) o;
+
+        return Objects.equals(this.ip, that.ip) &&
+                Objects.equals(this.mac, that.mac);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(ip, mac);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("ip", ip)
+                .add("mac", mac)
+                .toString();
+    }
+}
diff --git a/apps/bgprouter/src/main/java/org/onosproject/bgprouter/NextHopGroupKey.java b/apps/bgprouter/src/main/java/org/onosproject/bgprouter/NextHopGroupKey.java
new file mode 100644
index 0000000..5193f4b
--- /dev/null
+++ b/apps/bgprouter/src/main/java/org/onosproject/bgprouter/NextHopGroupKey.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.bgprouter;
+
+import com.google.common.base.MoreObjects;
+import org.onlab.packet.IpAddress;
+import org.onosproject.net.group.GroupKey;
+
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Created by jono on 2/16/15.
+ */
+public class NextHopGroupKey implements GroupKey {
+
+    private final IpAddress address;
+
+    public NextHopGroupKey(IpAddress address) {
+        this.address = checkNotNull(address);
+    }
+
+    public IpAddress address() {
+        return address;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof NextHopGroupKey)) {
+            return false;
+        }
+
+        NextHopGroupKey that = (NextHopGroupKey) o;
+
+        return Objects.equals(this.address, that.address);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(address);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("address", address)
+                .toString();
+    }
+}
diff --git a/apps/bgprouter/src/main/java/org/onosproject/bgprouter/TunnellingConnectivityManager.java b/apps/bgprouter/src/main/java/org/onosproject/bgprouter/TunnellingConnectivityManager.java
new file mode 100644
index 0000000..eac5ba9
--- /dev/null
+++ b/apps/bgprouter/src/main/java/org/onosproject/bgprouter/TunnellingConnectivityManager.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.bgprouter;
+
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.TCP;
+import org.onosproject.core.ApplicationId;
+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.packet.DefaultOutboundPacket;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketPriority;
+import org.onosproject.net.packet.PacketProcessor;
+import org.onosproject.net.packet.PacketService;
+import org.onosproject.routingapi.config.BgpPeer;
+import org.onosproject.routingapi.config.BgpSpeaker;
+import org.onosproject.routingapi.config.InterfaceAddress;
+import org.onosproject.routingapi.config.RoutingConfigurationService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Manages connectivity between peers by tunnelling BGP traffic through
+ * OpenFlow packet-ins and packet-outs.
+ */
+public class TunnellingConnectivityManager {
+
+    private static final short BGP_PORT = 179;
+
+    private final ApplicationId appId;
+
+    private final PacketService packetService;
+    private final RoutingConfigurationService configService;
+
+    private final BgpProcessor processor = new BgpProcessor();
+
+    public TunnellingConnectivityManager(ApplicationId appId,
+                                         RoutingConfigurationService configService,
+                                         PacketService packetService) {
+        this.appId = appId;
+        this.configService = configService;
+        this.packetService = packetService;
+    }
+
+    public void start() {
+        packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 3);
+
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+
+        // Request packets with BGP port as their TCP source port
+        selector.matchEthType(Ethernet.TYPE_IPV4);
+        selector.matchIPProtocol(IPv4.PROTOCOL_TCP);
+        selector.matchTcpSrc(BGP_PORT);
+
+        packetService.requestPackets(selector.build(), PacketPriority.CONTROL,
+                                     appId);
+
+        selector = DefaultTrafficSelector.builder();
+
+        // Request packets with BGP port as their TCP destination port
+        selector.matchEthType(Ethernet.TYPE_IPV4);
+        selector.matchIPProtocol(IPv4.PROTOCOL_TCP);
+        selector.matchTcpDst(BGP_PORT);
+
+        packetService.requestPackets(selector.build(), PacketPriority.CONTROL,
+                                     appId);
+    }
+
+    public void stop() {
+        packetService.removeProcessor(processor);
+        // Should revoke packet requests in the future
+    }
+
+    /**
+     * Forwards a BGP packet to another connect point.
+     *
+     * @param context the packet context of the incoming packet
+     */
+    private void forward(PacketContext context) {
+
+        ConnectPoint outputPort = null;
+        Logger log = LoggerFactory.getLogger(getClass());
+
+
+        IPv4 ipv4 = (IPv4) context.inPacket().parsed().getPayload();
+        IpAddress dstAddress = IpAddress.valueOf(ipv4.getDestinationAddress());
+
+        for (BgpSpeaker speaker : configService.getBgpSpeakers().values()) {
+            if (context.inPacket().receivedFrom().equals(speaker.connectPoint())) {
+                BgpPeer peer = configService.getBgpPeers().get(dstAddress);
+                if (peer != null) {
+                    outputPort = peer.connectPoint();
+                }
+                break;
+            }
+            for (InterfaceAddress addr : speaker.interfaceAddresses()) {
+                if (addr.ipAddress().equals(dstAddress) && !context.inPacket()
+                        .receivedFrom().equals(speaker.connectPoint())) {
+                    outputPort = speaker.connectPoint();
+                }
+            }
+        }
+
+        if (outputPort != null) {
+            TrafficTreatment t = DefaultTrafficTreatment.builder()
+                    .setOutput(outputPort.port()).build();
+            OutboundPacket o = new DefaultOutboundPacket(
+                    outputPort.deviceId(), t, context.inPacket().unparsed());
+            packetService.emit(o);
+        }
+    }
+
+    /**
+     * Packet processor responsible receiving and filtering BGP packets.
+     */
+    private class BgpProcessor implements PacketProcessor {
+
+        @Override
+        public void process(PacketContext context) {
+            // Stop processing if the packet has been handled, since we
+            // can't do any more to it.
+            if (context.isHandled()) {
+                return;
+            }
+
+            Ethernet packet = context.inPacket().parsed();
+
+            if (packet == null) {
+                return;
+            }
+
+            if (packet.getEtherType() == Ethernet.TYPE_IPV4) {
+                IPv4 ipv4Packet = (IPv4) packet.getPayload();
+                if (ipv4Packet.getProtocol() == IPv4.PROTOCOL_TCP) {
+                    TCP tcpPacket = (TCP) ipv4Packet.getPayload();
+
+                    if (tcpPacket.getDestinationPort() == BGP_PORT ||
+                            tcpPacket.getSourcePort() == BGP_PORT) {
+                        forward(context);
+                    }
+                }
+            }
+        }
+    }
+}
