diff --git a/apps/routing/fibinstaller/BUCK b/apps/routing/fibinstaller/BUCK
new file mode 100644
index 0000000..b77e51b
--- /dev/null
+++ b/apps/routing/fibinstaller/BUCK
@@ -0,0 +1,30 @@
+COMPILE_DEPS = [
+    '//lib:CORE_DEPS',
+    '//incubator/api:onos-incubator-api',
+    '//apps/routing-api:onos-apps-routing-api',
+]
+
+TEST_DEPS = [
+    '//lib:TEST_ADAPTERS',
+    '//incubator/api:onos-incubator-api-tests',
+    '//apps/routing-api:onos-apps-routing-api-tests',
+]
+
+osgi_jar_with_tests (
+    deps = COMPILE_DEPS,
+    test_deps = TEST_DEPS,
+)
+
+BUNDLES = [
+    '//apps/routing/fibinstaller:onos-apps-routing-fibinstaller',
+    '//apps/routing-api:onos-apps-routing-api',
+]
+
+onos_app (
+    app_name = 'org.onosproject.fibinstaller',
+    title = 'FIB installer app',
+    category = 'Traffic Steering',
+    url = 'http://onosproject.org',
+    description = 'Installs routing rules into switches',
+    included_bundles = BUNDLES,
+)
diff --git a/apps/routing/fibinstaller/pom.xml b/apps/routing/fibinstaller/pom.xml
new file mode 100644
index 0000000..5cb98e6
--- /dev/null
+++ b/apps/routing/fibinstaller/pom.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2017-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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>onos-app-routing-parent</artifactId>
+        <groupId>org.onosproject</groupId>
+        <version>1.9.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>onos-apps-routing-fibinstaller</artifactId>
+    <packaging>bundle</packaging>
+
+
+</project>
diff --git a/apps/routing/fibinstaller/src/main/java/org/onosproject/routing/fibinstaller/SingleSwitchFibInstaller.java b/apps/routing/fibinstaller/src/main/java/org/onosproject/routing/fibinstaller/SingleSwitchFibInstaller.java
new file mode 100644
index 0000000..c6b3af4
--- /dev/null
+++ b/apps/routing/fibinstaller/src/main/java/org/onosproject/routing/fibinstaller/SingleSwitchFibInstaller.java
@@ -0,0 +1,567 @@
+/*
+ * Copyright 2017-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.routing.fibinstaller;
+
+import com.google.common.collect.ConcurrentHashMultiset;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Multiset;
+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;
+import org.apache.felix.scr.annotations.Modified;
+import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onlab.util.Tools;
+import org.onosproject.app.ApplicationService;
+import org.onosproject.cfg.ComponentConfigService;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.incubator.net.config.basics.McastConfig;
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.incubator.net.intf.InterfaceService;
+import org.onosproject.incubator.net.routing.ResolvedRoute;
+import org.onosproject.incubator.net.routing.RouteEvent;
+import org.onosproject.incubator.net.routing.RouteListener;
+import org.onosproject.incubator.net.routing.RouteService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.config.ConfigFactory;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.config.NetworkConfigRegistry;
+import org.onosproject.net.config.NetworkConfigService;
+import org.onosproject.net.config.basics.SubjectFactories;
+import org.onosproject.net.device.DeviceService;
+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.Criteria;
+import org.onosproject.net.flowobjective.DefaultFilteringObjective;
+import org.onosproject.net.flowobjective.DefaultForwardingObjective;
+import org.onosproject.net.flowobjective.DefaultNextObjective;
+import org.onosproject.net.flowobjective.DefaultObjectiveContext;
+import org.onosproject.net.flowobjective.FilteringObjective;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.NextObjective;
+import org.onosproject.net.flowobjective.ObjectiveContext;
+import org.onosproject.routing.AsyncDeviceFetcher;
+import org.onosproject.routing.NextHop;
+import org.onosproject.routing.NextHopGroupKey;
+import org.onosproject.routing.RouterInterfaceManager;
+import org.onosproject.routing.RoutingService;
+import org.onosproject.routing.config.RouterConfig;
+import org.osgi.service.component.ComponentContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Dictionary;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Programs routes to a single OpenFlow switch.
+ */
+@Component(immediate = true)
+public class SingleSwitchFibInstaller {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+    private static final String APP_NAME = "org.onosproject.vrouter";
+
+    private static final int PRIORITY_OFFSET = 100;
+    private static final int PRIORITY_MULTIPLIER = 5;
+
+    // FIXME: This should be eliminated when we have an API in SR that
+    //        programs the fabric switches for VR
+    public static final short ASSIGNED_VLAN = 4094;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected RouteService routeService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected InterfaceService interfaceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigService networkConfigService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigRegistry networkConfigRegistry;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ComponentConfigService componentConfigService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected FlowObjectiveService flowObjectiveService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ApplicationService applicationService;
+
+    @Property(name = "routeToNextHop", boolValue = false,
+            label = "Install a /32 or /128 route to each next hop")
+    private boolean routeToNextHop = false;
+
+    // Device id of data-plane switch - should be learned from config
+    private DeviceId deviceId;
+
+    private ConnectPoint controlPlaneConnectPoint;
+
+    private RouterInterfaceManager interfaceManager;
+    private AsyncDeviceFetcher asyncDeviceFetcher;
+
+    private ApplicationId coreAppId;
+    private ApplicationId routerAppId;
+    private ApplicationId vrouterAppId;
+
+    // Reference count for how many times a next hop is used by a route
+    private final Multiset<IpAddress> nextHopsCount = ConcurrentHashMultiset.create();
+
+    // Mapping from prefix to its current next hop
+    private final Map<IpPrefix, IpAddress> prefixToNextHop = Maps.newHashMap();
+
+    // Mapping from next hop IP to next hop object containing group info
+    private final Map<IpAddress, Integer> nextHops = Maps.newHashMap();
+
+    private final InternalRouteListener routeListener = new InternalRouteListener();
+    private final InternalNetworkConfigListener configListener = new InternalNetworkConfigListener();
+
+    private ConfigFactory<ApplicationId, McastConfig> mcastConfigFactory =
+            new ConfigFactory<ApplicationId, McastConfig>(SubjectFactories.APP_SUBJECT_FACTORY,
+                    McastConfig.class, "multicast") {
+                @Override
+                public McastConfig createConfig() {
+                    return new McastConfig();
+                }
+            };
+
+    @Activate
+    protected void activate(ComponentContext context) {
+        componentConfigService.registerProperties(getClass());
+        modified(context);
+
+        coreAppId = coreService.registerApplication(CoreService.CORE_APP_NAME);
+        routerAppId = coreService.registerApplication(RoutingService.ROUTER_APP_ID);
+        vrouterAppId = coreService.registerApplication(APP_NAME);
+
+        networkConfigRegistry.registerConfigFactory(mcastConfigFactory);
+
+        networkConfigService.addListener(configListener);
+
+        asyncDeviceFetcher = AsyncDeviceFetcher.create(deviceService);
+
+        processRouterConfig();
+
+        // FIXME: There can be an issue when this component is deactivated before vRouter.
+        //        This will be addressed in CORD-710.
+        applicationService.registerDeactivateHook(vrouterAppId, () -> cleanUp());
+
+        log.info("Started");
+    }
+
+    @Deactivate
+    protected void deactivate() {
+         // FIXME: This will also remove flows when an instance goes down.
+         //        This is a temporary solution and should be addressed in CORD-710.
+        cleanUp();
+
+        asyncDeviceFetcher.shutdown();
+        networkConfigService.removeListener(configListener);
+
+        componentConfigService.unregisterProperties(getClass(), false);
+
+        log.info("Stopped");
+    }
+
+    @Modified
+    protected void modified(ComponentContext context) {
+        Dictionary<?, ?> properties = context.getProperties();
+        if (properties == null) {
+            return;
+        }
+
+        String strRouteToNextHop = Tools.get(properties, "routeToNextHop");
+        routeToNextHop = Boolean.parseBoolean(strRouteToNextHop);
+
+        log.info("routeToNextHop set to {}", routeToNextHop);
+    }
+
+    private void processRouterConfig() {
+        RouterConfig routerConfig =
+                networkConfigService.getConfig(routerAppId, RoutingService.ROUTER_CONFIG_CLASS);
+
+        if (routerConfig == null) {
+            log.info("Router config not available");
+            return;
+        }
+
+        Set<String> interfaces = Sets.newHashSet(routerConfig.getInterfaces());
+
+        if (deviceId == null) {
+            controlPlaneConnectPoint = routerConfig.getControlPlaneConnectPoint();
+            log.info("Control Plane Connect Point: {}", controlPlaneConnectPoint);
+
+            deviceId = routerConfig.getControlPlaneConnectPoint().deviceId();
+            log.info("Router device ID is {}", deviceId);
+
+            routeService.addListener(routeListener);
+            asyncDeviceFetcher.getDevice(deviceId).whenComplete((deviceId, e) ->
+                    interfaceManager = createRouter(deviceId, interfaces));
+        } else {
+            interfaceManager.changeConfiguredInterfaces(interfaces);
+        }
+    }
+
+    /*
+     * Removes filtering objectives and routes before deactivate.
+     */
+    private void cleanUp() {
+        //remove the route listener
+        routeService.removeListener(routeListener);
+
+        //clean up the routes.
+        for (Map.Entry<IpPrefix, IpAddress> routes: prefixToNextHop.entrySet()) {
+            deleteRoute(new ResolvedRoute(routes.getKey(), null, null, null));
+        }
+
+        if (interfaceManager != null) {
+            interfaceManager.cleanup();
+        }
+    }
+
+    private RouterInterfaceManager createRouter(DeviceId deviceId, Set<String> configuredInterfaces) {
+        return new RouterInterfaceManager(deviceId,
+                configuredInterfaces,
+                interfaceService,
+                this::provisionInterface,
+                this::unprovisionInterface);
+    }
+
+    private void updateRoute(ResolvedRoute route) {
+        addNextHop(route);
+
+        Integer nextId;
+        synchronized (this) {
+            nextId = nextHops.get(route.nextHop());
+        }
+
+        flowObjectiveService.forward(deviceId,
+                generateRibForwardingObj(route.prefix(), nextId).add());
+        log.trace("Sending forwarding objective {} -> nextId:{}", route, nextId);
+    }
+
+    private synchronized void deleteRoute(ResolvedRoute route) {
+        //Integer nextId = nextHops.get(route.nextHop());
+
+        /* Group group = deleteNextHop(route.prefix());
+        if (group == null) {
+            log.warn("Group not found when deleting {}", route);
+            return;
+        }*/
+
+        flowObjectiveService.forward(deviceId,
+                generateRibForwardingObj(route.prefix(), null).remove());
+    }
+
+    private ForwardingObjective.Builder generateRibForwardingObj(IpPrefix prefix,
+                                                                 Integer nextId) {
+        TrafficSelector selector = buildIpSelectorFromIpPrefix(prefix).build();
+        int priority = prefix.prefixLength() * PRIORITY_MULTIPLIER + PRIORITY_OFFSET;
+
+        ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective.builder()
+                .fromApp(routerAppId)
+                .makePermanent()
+                .withSelector(selector)
+                .withPriority(priority)
+                .withFlag(ForwardingObjective.Flag.SPECIFIC);
+
+        if (nextId == null) {
+            // Route withdraws are not specified with next hops. Generating
+            // dummy treatment as there is no equivalent nextId info.
+            fwdBuilder.withTreatment(DefaultTrafficTreatment.builder().build());
+        } else {
+            fwdBuilder.nextStep(nextId);
+        }
+        return fwdBuilder;
+    }
+
+    /**
+     * Method to build IPv4 or IPv6 selector.
+     *
+     * @param prefixToMatch the prefix to match
+     * @return the traffic selector builder
+     */
+    private TrafficSelector.Builder buildIpSelectorFromIpPrefix(IpPrefix prefixToMatch) {
+        TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
+        // If the prefix is IPv4
+        if (prefixToMatch.isIp4()) {
+            selectorBuilder.matchEthType(Ethernet.TYPE_IPV4);
+            selectorBuilder.matchIPDst(prefixToMatch);
+            return selectorBuilder;
+        }
+        // If the prefix is IPv6
+        selectorBuilder.matchEthType(Ethernet.TYPE_IPV6);
+        selectorBuilder.matchIPv6Dst(prefixToMatch);
+        return selectorBuilder;
+    }
+
+    private synchronized void addNextHop(ResolvedRoute route) {
+        prefixToNextHop.put(route.prefix(), route.nextHop());
+        if (nextHopsCount.count(route.nextHop()) == 0) {
+            // There was no next hop in the multiset
+            Interface egressIntf = interfaceService.getMatchingInterface(route.nextHop());
+            if (egressIntf == null) {
+                log.warn("no egress interface found for {}", route);
+                return;
+            }
+
+            NextHopGroupKey groupKey = new NextHopGroupKey(route.nextHop());
+
+            NextHop nextHop = new NextHop(route.nextHop(), route.nextHopMac(), groupKey);
+
+            TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder()
+                    .setEthSrc(egressIntf.mac())
+                    .setEthDst(nextHop.mac());
+
+            TrafficSelector.Builder metabuilder = null;
+            if (!egressIntf.vlan().equals(VlanId.NONE)) {
+                treatment.pushVlan()
+                        .setVlanId(egressIntf.vlan())
+                        .setVlanPcp((byte) 0);
+            } else {
+                // untagged outgoing port may require internal vlan in some pipelines
+                metabuilder = DefaultTrafficSelector.builder();
+                metabuilder.matchVlanId(VlanId.vlanId(ASSIGNED_VLAN));
+            }
+
+            treatment.setOutput(egressIntf.connectPoint().port());
+
+            int nextId = flowObjectiveService.allocateNextId();
+            NextObjective.Builder nextBuilder = DefaultNextObjective.builder()
+                    .withId(nextId)
+                    .addTreatment(treatment.build())
+                    .withType(NextObjective.Type.SIMPLE)
+                    .fromApp(routerAppId);
+            if (metabuilder != null) {
+                nextBuilder.withMeta(metabuilder.build());
+            }
+
+            NextObjective nextObjective = nextBuilder.add(); // TODO add callbacks
+            flowObjectiveService.next(deviceId, nextObjective);
+
+            nextHops.put(nextHop.ip(), nextId);
+
+            if (routeToNextHop) {
+                // Install route to next hop
+                ForwardingObjective fob =
+                        generateRibForwardingObj(IpPrefix.valueOf(route.nextHop(), 32), nextId).add();
+                flowObjectiveService.forward(deviceId, fob);
+            }
+        }
+
+        nextHopsCount.add(route.nextHop());
+    }
+
+    /*private synchronized Group deleteNextHop(IpPrefix prefix) {
+        IpAddress nextHopIp = prefixToNextHop.remove(prefix);
+        NextHop nextHop = nextHops.get(nextHopIp);
+        if (nextHop == null) {
+            log.warn("No next hop found when removing prefix {}", prefix);
+            return null;
+        }
+
+        Group group = groupService.getGroup(deviceId,
+                                            new DefaultGroupKey(appKryo.
+                                                                serialize(nextHop.group())));
+
+        // FIXME disabling group deletes for now until we verify the logic is OK
+        if (nextHopsCount.remove(nextHopIp, 1) <= 1) {
+            // There was one or less next hops, so there are now none
+
+            log.debug("removing group for next hop {}", nextHop);
+
+            nextHops.remove(nextHopIp);
+
+            groupService.removeGroup(deviceId,
+                                     new DefaultGroupKey(appKryo.build().serialize(nextHop.group())),
+                                     appId);
+        }
+
+        return group;
+    }*/
+
+    private void provisionInterface(Interface intf) {
+        updateInterfaceFilters(intf, true);
+    }
+
+    private void unprovisionInterface(Interface intf) {
+        updateInterfaceFilters(intf, false);
+    }
+
+    /**
+     * Installs or removes flow objectives relating to an interface.
+     *
+     * @param intf interface to update objectives for
+     * @param install true to install the objectives, false to remove them
+     */
+    private void updateInterfaceFilters(Interface intf, boolean install) {
+        updateFilteringObjective(intf, install);
+        updateMcastFilteringObjective(intf, install);
+    }
+
+    /**
+     * Installs or removes unicast filtering objectives relating to an interface.
+     *
+     * @param intf interface to update objectives for
+     * @param install true to install the objectives, false to remove them
+     */
+    private void updateFilteringObjective(Interface intf, boolean install) {
+        VlanId assignedVlan = (egressVlan().equals(VlanId.NONE)) ?
+                VlanId.vlanId(ASSIGNED_VLAN) :
+                egressVlan();
+
+        FilteringObjective.Builder fob = DefaultFilteringObjective.builder();
+        // first add filter for the interface
+        fob.withKey(Criteria.matchInPort(intf.connectPoint().port()))
+            .addCondition(Criteria.matchEthDst(intf.mac()))
+            .addCondition(Criteria.matchVlanId(intf.vlan()));
+        fob.withPriority(PRIORITY_OFFSET);
+        if (intf.vlan() == VlanId.NONE) {
+            TrafficTreatment tt = DefaultTrafficTreatment.builder()
+                    .pushVlan().setVlanId(assignedVlan).build();
+            fob.withMeta(tt);
+        }
+        fob.permit().fromApp(routerAppId);
+        sendFilteringObjective(install, fob, intf);
+
+        if (controlPlaneConnectPoint != null) {
+            // then add the same mac/vlan filters for control-plane connect point
+            fob.withKey(Criteria.matchInPort(controlPlaneConnectPoint.port()));
+            sendFilteringObjective(install, fob, intf);
+        }
+    }
+
+    /**
+     * Installs or removes multicast filtering objectives relating to an interface.
+     *
+     * @param intf interface to update objectives for
+     * @param install true to install the objectives, false to remove them
+     */
+    private void updateMcastFilteringObjective(Interface intf, boolean install) {
+        VlanId assignedVlan = (egressVlan().equals(VlanId.NONE)) ?
+                VlanId.vlanId(ASSIGNED_VLAN) :
+                egressVlan();
+
+        FilteringObjective.Builder fob = DefaultFilteringObjective.builder();
+        // first add filter for the interface
+        fob.withKey(Criteria.matchInPort(intf.connectPoint().port()))
+                .addCondition(Criteria.matchEthDstMasked(MacAddress.IPV4_MULTICAST,
+                        MacAddress.IPV4_MULTICAST_MASK))
+                .addCondition(Criteria.matchVlanId(ingressVlan()));
+        fob.withPriority(PRIORITY_OFFSET);
+        TrafficTreatment tt = DefaultTrafficTreatment.builder()
+                .pushVlan().setVlanId(assignedVlan).build();
+        fob.withMeta(tt);
+
+        fob.permit().fromApp(routerAppId);
+        sendFilteringObjective(install, fob, intf);
+    }
+
+    private void sendFilteringObjective(boolean install, FilteringObjective.Builder fob,
+                                        Interface intf) {
+
+        ObjectiveContext context = new DefaultObjectiveContext(
+                (objective) -> log.info("Installed filter for interface {}", intf),
+                (objective, error) ->
+                        log.error("Failed to install filter for interface {}: {}", intf, error));
+
+        FilteringObjective filter = install ? fob.add(context) : fob.remove(context);
+
+        flowObjectiveService.filter(deviceId, filter);
+    }
+
+    private VlanId ingressVlan() {
+        McastConfig mcastConfig =
+                networkConfigService.getConfig(coreAppId, McastConfig.class);
+        return (mcastConfig != null) ? mcastConfig.ingressVlan() : VlanId.NONE;
+    }
+
+    private VlanId egressVlan() {
+        McastConfig mcastConfig =
+                networkConfigService.getConfig(coreAppId, McastConfig.class);
+        return (mcastConfig != null) ? mcastConfig.egressVlan() : VlanId.NONE;
+    }
+
+    /**
+     * Listener for route changes.
+     */
+    private class InternalRouteListener implements RouteListener {
+        @Override
+        public void event(RouteEvent event) {
+            ResolvedRoute route = event.subject();
+            switch (event.type()) {
+            case ROUTE_ADDED:
+            case ROUTE_UPDATED:
+                updateRoute(route);
+                break;
+            case ROUTE_REMOVED:
+                deleteRoute(route);
+                break;
+            default:
+                break;
+            }
+        }
+    }
+
+    /**
+     * Listener for network config events.
+     */
+    private class InternalNetworkConfigListener implements NetworkConfigListener {
+        @Override
+        public void event(NetworkConfigEvent event) {
+            if (event.configClass().equals(RoutingService.ROUTER_CONFIG_CLASS)) {
+                switch (event.type()) {
+                case CONFIG_ADDED:
+                case CONFIG_UPDATED:
+                    processRouterConfig();
+                    break;
+                case CONFIG_REGISTERED:
+                    break;
+                case CONFIG_UNREGISTERED:
+                    break;
+                case CONFIG_REMOVED:
+                    cleanUp();
+                    break;
+                default:
+                    break;
+                }
+            }
+        }
+    }
+}
diff --git a/apps/routing/fibinstaller/src/main/java/org/onosproject/routing/fibinstaller/package-info.java b/apps/routing/fibinstaller/src/main/java/org/onosproject/routing/fibinstaller/package-info.java
new file mode 100644
index 0000000..669754d
--- /dev/null
+++ b/apps/routing/fibinstaller/src/main/java/org/onosproject/routing/fibinstaller/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-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.
+ */
+
+/**
+ * Single switch FIB installer.
+ */
+package org.onosproject.routing.fibinstaller;
diff --git a/apps/routing/fibinstaller/src/test/java/org/onosproject/routing/fibinstaller/SingleSwitchFibInstallerTest.java b/apps/routing/fibinstaller/src/test/java/org/onosproject/routing/fibinstaller/SingleSwitchFibInstallerTest.java
new file mode 100644
index 0000000..f7736f7
--- /dev/null
+++ b/apps/routing/fibinstaller/src/test/java/org/onosproject/routing/fibinstaller/SingleSwitchFibInstallerTest.java
@@ -0,0 +1,431 @@
+/*
+ * Copyright 2017-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.routing.fibinstaller;
+
+import com.google.common.collect.Sets;
+import org.easymock.EasyMock;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.Ip4Prefix;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.TestApplicationId;
+import org.onosproject.app.ApplicationService;
+import org.onosproject.cfg.ComponentConfigService;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.incubator.net.intf.InterfaceListener;
+import org.onosproject.incubator.net.intf.InterfaceService;
+import org.onosproject.incubator.net.intf.InterfaceServiceAdapter;
+import org.onosproject.incubator.net.routing.ResolvedRoute;
+import org.onosproject.incubator.net.routing.RouteEvent;
+import org.onosproject.incubator.net.routing.RouteListener;
+import org.onosproject.incubator.net.routing.RouteServiceAdapter;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.config.NetworkConfigRegistry;
+import org.onosproject.net.config.NetworkConfigService;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.device.DeviceServiceAdapter;
+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.flowobjective.DefaultForwardingObjective;
+import org.onosproject.net.flowobjective.DefaultNextObjective;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.NextObjective;
+import org.onosproject.net.host.InterfaceIpAddress;
+import org.onosproject.routing.RoutingService;
+import org.onosproject.routing.config.RouterConfig;
+import org.osgi.service.component.ComponentContext;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.anyString;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.reset;
+import static org.easymock.EasyMock.verify;
+
+/**
+ * Unit tests for SingleSwitchFibInstaller.
+ */
+public class SingleSwitchFibInstallerTest {
+
+    private static final DeviceId DEVICE_ID = DeviceId.deviceId("of:0000000000000001");
+
+    private static final ConnectPoint SW1_ETH1 = new ConnectPoint(
+            DEVICE_ID, PortNumber.portNumber(1));
+
+    private static final ConnectPoint SW1_ETH2 = new ConnectPoint(
+            DEVICE_ID, PortNumber.portNumber(2));
+
+    private static final int NEXT_ID = 11;
+
+    private static final VlanId VLAN1 = VlanId.vlanId((short) 1);
+    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 IpPrefix PREFIX1 = Ip4Prefix.valueOf("1.1.1.0/24");
+    private static final IpAddress NEXT_HOP1 = IpAddress.valueOf("192.168.10.1");
+    private static final IpAddress NEXT_HOP2 = IpAddress.valueOf("192.168.20.1");
+    private static final InterfaceIpAddress INTF1 =
+            InterfaceIpAddress.valueOf("192.168.10.2/24");
+    private static final InterfaceIpAddress INTF2 =
+            InterfaceIpAddress.valueOf("192.168.20.2/24");
+
+    private final Set<Interface> interfaces = Sets.newHashSet();
+    private InterfaceService interfaceService;
+    private NetworkConfigService networkConfigService;
+    private NetworkConfigRegistry networkConfigRegistry;
+    private FlowObjectiveService flowObjectiveService;
+    private ApplicationService applicationService;
+    private DeviceService deviceService;
+    private static final ApplicationId APPID = TestApplicationId.create("foo");
+
+    private RouteListener routeListener;
+    private DeviceListener deviceListener;
+
+    private RouterConfig routerConfig;
+    private SingleSwitchFibInstaller sSfibInstaller;
+    private InterfaceListener interfaceListener;
+
+    @Before
+    public void setUp() throws Exception {
+        sSfibInstaller = new SingleSwitchFibInstaller();
+
+        sSfibInstaller.componentConfigService = createNiceMock(ComponentConfigService.class);
+
+        ComponentContext mockContext = createNiceMock(ComponentContext.class);
+
+        routerConfig = new TestRouterConfig();
+        interfaceService = createMock(InterfaceService.class);
+
+        networkConfigService = createMock(NetworkConfigService.class);
+        networkConfigService.addListener(anyObject(NetworkConfigListener.class));
+        expectLastCall().anyTimes();
+        networkConfigRegistry = createMock(NetworkConfigRegistry.class);
+        flowObjectiveService = createMock(FlowObjectiveService.class);
+        applicationService = createNiceMock(ApplicationService.class);
+        replay(applicationService);
+        deviceService = new TestDeviceService();
+        CoreService coreService = createNiceMock(CoreService.class);
+        expect(coreService.registerApplication(anyString())).andReturn(APPID).anyTimes();
+        replay(coreService);
+
+        sSfibInstaller.networkConfigService = networkConfigService;
+        sSfibInstaller.networkConfigRegistry = networkConfigRegistry;
+        sSfibInstaller.interfaceService = interfaceService;
+        sSfibInstaller.flowObjectiveService = flowObjectiveService;
+        sSfibInstaller.applicationService = applicationService;
+        sSfibInstaller.coreService = coreService;
+        sSfibInstaller.routeService = new TestRouteService();
+        sSfibInstaller.deviceService = deviceService;
+
+        setUpNetworkConfigService();
+        setUpInterfaceService();
+        sSfibInstaller.activate(mockContext);
+    }
+
+    /**
+     * Sets up InterfaceService.
+     */
+    private void setUpInterfaceService() {
+        interfaceService.addListener(anyObject(InterfaceListener.class));
+        expectLastCall().andDelegateTo(new TestInterfaceService());
+
+        // Interface with no VLAN
+        Interface sw1Eth1 = new Interface("intf1", SW1_ETH1,
+                Collections.singletonList(INTF1), MAC1, VlanId.NONE);
+        expect(interfaceService.getMatchingInterface(NEXT_HOP1)).andReturn(sw1Eth1);
+        interfaces.add(sw1Eth1);
+
+        // Interface with a VLAN
+        Interface sw2Eth1 = new Interface("intf2", SW1_ETH2,
+                Collections.singletonList(INTF2), MAC2, VLAN1);
+        expect(interfaceService.getMatchingInterface(NEXT_HOP2)).andReturn(sw2Eth1);
+        interfaces.add(sw2Eth1);
+
+        expect(interfaceService.getInterfaces()).andReturn(interfaces);
+
+        replay(interfaceService);
+    }
+
+    /*
+     * Sets up NetworkConfigService.
+     */
+    private void setUpNetworkConfigService() {
+        expect(networkConfigService.getConfig(
+                anyObject(ApplicationId.class), eq(RoutingService.ROUTER_CONFIG_CLASS))).
+        andReturn(routerConfig);
+        replay(networkConfigService);
+    }
+
+    /**
+     * Sets up FlowObjectiveService.
+     */
+    private void setUpFlowObjectiveService() {
+        expect(flowObjectiveService.allocateNextId()).andReturn(NEXT_ID);
+        replay(flowObjectiveService);
+    }
+
+    /**
+     * Creates a next objective with the given parameters.
+     *
+     * @param srcMac source MAC address
+     * @param dstMac destination MAC address
+     * @param port port number
+     * @param vlan vlan ID
+     * @param add whether to create an add objective or remove objective
+     * @return new next objective
+     */
+    private NextObjective createNextObjective(MacAddress srcMac,
+                                              MacAddress dstMac,
+                                              PortNumber port,
+                                              VlanId vlan,
+                                              boolean add) {
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder()
+                .setEthSrc(srcMac)
+                .setEthDst(dstMac);
+        TrafficSelector.Builder metabuilder = null;
+        if (!vlan.equals(VlanId.NONE)) {
+            treatment.pushVlan()
+                     .setVlanId(vlan)
+                     .setVlanPcp((byte) 0);
+        } else {
+            metabuilder = DefaultTrafficSelector.builder();
+            metabuilder.matchVlanId(VlanId.vlanId(SingleSwitchFibInstaller.ASSIGNED_VLAN));
+        }
+
+        treatment.setOutput(port);
+        NextObjective.Builder nextBuilder = DefaultNextObjective.builder()
+                .withId(NEXT_ID)
+                .addTreatment(treatment.build())
+                .withType(NextObjective.Type.SIMPLE)
+                .fromApp(APPID);
+        if (metabuilder != null) {
+            nextBuilder.withMeta(metabuilder.build());
+        }
+
+        return add ? nextBuilder.add() : nextBuilder.remove();
+    }
+
+    /**
+     * Creates a new forwarding objective with the given parameters.
+     *
+     * @param prefix IP prefix
+     * @param add whether to create an add objective or a remove objective
+     * @return new forwarding objective
+     */
+    private ForwardingObjective createForwardingObjective(IpPrefix prefix,
+                                                          boolean add) {
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchEthType(Ethernet.TYPE_IPV4)
+                .matchIPDst(prefix)
+                .build();
+
+        int priority = prefix.prefixLength() * 5 + 100;
+        ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective.builder()
+                .fromApp(APPID)
+                .makePermanent()
+                .withSelector(selector)
+                .withPriority(priority)
+                .withFlag(ForwardingObjective.Flag.SPECIFIC);
+
+        if (add) {
+            fwdBuilder.nextStep(NEXT_ID);
+        } else {
+            fwdBuilder.withTreatment(DefaultTrafficTreatment.builder().build());
+        }
+
+        return add ? fwdBuilder.add() : fwdBuilder.remove();
+    }
+
+    /**
+     * Tests adding a route.
+     *
+     * We verify that the flowObjectiveService records the correct state and that the
+     * correct flow is submitted to the flowObjectiveService.
+     */
+    @Test
+    public void testRouteAdd() {
+        ResolvedRoute resolvedRoute = new ResolvedRoute(PREFIX1, NEXT_HOP1, MAC1, SW1_ETH1);
+
+        // Create the next objective
+        NextObjective nextObjective = createNextObjective(MAC1, MAC1, SW1_ETH1.port(), VlanId.NONE, true);
+        flowObjectiveService.next(DEVICE_ID, nextObjective);
+
+        // Create the flow objective
+        ForwardingObjective fwd = createForwardingObjective(PREFIX1, true);
+        flowObjectiveService.forward(DEVICE_ID, fwd);
+        EasyMock.expectLastCall().once();
+        setUpFlowObjectiveService();
+
+        // Send in the add event
+        RouteEvent routeEvent = new RouteEvent(RouteEvent.Type.ROUTE_ADDED, resolvedRoute);
+        routeListener.event(routeEvent);
+        verify(flowObjectiveService);
+    }
+
+    /**
+     * Tests adding a route with to a next hop in a VLAN.
+     *
+     * We verify that the flowObjectiveService records the correct state and that the
+     * correct flowObjectiveService is submitted to the flowObjectiveService.
+     */
+    @Test
+    public void testRouteAddWithVlan() {
+        ResolvedRoute route = new ResolvedRoute(PREFIX1, NEXT_HOP2, MAC2, SW1_ETH2);
+
+        // Create the next objective
+        NextObjective nextObjective = createNextObjective(MAC2, MAC2, SW1_ETH2.port(), VLAN1, true);
+        flowObjectiveService.next(DEVICE_ID, nextObjective);
+
+        // Create the flow objective
+        ForwardingObjective fwd = createForwardingObjective(PREFIX1, true);
+        flowObjectiveService.forward(DEVICE_ID, fwd);
+        EasyMock.expectLastCall().once();
+        setUpFlowObjectiveService();
+
+        // Send in the add event
+        routeListener.event(new RouteEvent(RouteEvent.Type.ROUTE_ADDED, route));
+
+        verify(flowObjectiveService);
+    }
+
+    /**
+     * Tests updating a route.
+     *
+     * We verify that the flowObjectiveService records the correct state and that the
+     * correct flow is submitted to the flowObjectiveService.
+     */
+    @Test
+    public void testRouteUpdate() {
+        // Firstly add a route
+        testRouteAdd();
+        reset(flowObjectiveService);
+
+        ResolvedRoute oldRoute = new ResolvedRoute(PREFIX1, NEXT_HOP1, MAC1, SW1_ETH1);
+        ResolvedRoute route = new ResolvedRoute(PREFIX1, NEXT_HOP2, MAC2, SW1_ETH2);
+
+        // Create the next objective
+        NextObjective nextObjective = createNextObjective(MAC2, MAC2, SW1_ETH2.port(), VLAN1, true);
+        flowObjectiveService.next(DEVICE_ID, nextObjective);
+
+        // Create the flow objective
+        ForwardingObjective fwd = createForwardingObjective(PREFIX1, true);
+        flowObjectiveService.forward(DEVICE_ID, fwd);
+        EasyMock.expectLastCall().once();
+        setUpFlowObjectiveService();
+
+        // Send in the update event
+        routeListener.event(new RouteEvent(RouteEvent.Type.ROUTE_UPDATED, route, oldRoute));
+
+        verify(flowObjectiveService);
+    }
+
+    /**
+     * Tests deleting a route.
+     *
+     * We verify that the flowObjectiveService records the correct state and that the
+     * correct flow is withdrawn from the flowObjectiveService.
+     */
+    @Test
+    public void testRouteDelete() {
+        // Firstly add a route
+        testRouteAdd();
+
+        // Construct the existing route
+        ResolvedRoute route = new ResolvedRoute(PREFIX1, NEXT_HOP1, MAC1, SW1_ETH1);
+
+        // Create the flow objective
+        reset(flowObjectiveService);
+        ForwardingObjective fwd = createForwardingObjective(PREFIX1, false);
+        flowObjectiveService.forward(DEVICE_ID, fwd);
+        replay(flowObjectiveService);
+
+        // Send in the delete event
+        routeListener.event(new RouteEvent(RouteEvent.Type.ROUTE_REMOVED, route));
+
+        verify(flowObjectiveService);
+    }
+
+    private class TestInterfaceService extends InterfaceServiceAdapter {
+        @Override
+        public void addListener(InterfaceListener listener) {
+            interfaceListener = listener;
+        }
+    }
+
+    private class TestRouteService extends RouteServiceAdapter {
+        @Override
+        public void addListener(RouteListener listener) {
+            SingleSwitchFibInstallerTest.this.routeListener = listener;
+        }
+    }
+
+    private class TestRouterConfig extends RouterConfig {
+
+        @Override
+        public List<String> getInterfaces() {
+            ArrayList<String> interfaces = new ArrayList<>();
+            interfaces.add("of:0000000000000001/1");
+            interfaces.add("of:0000000000000001/2");
+            return interfaces;
+        }
+
+        @Override
+        public ConnectPoint getControlPlaneConnectPoint() {
+            return SW1_ETH1;
+        }
+
+        @Override
+        public boolean getOspfEnabled() {
+            return true;
+        }
+    }
+
+    private class TestDeviceService  extends DeviceServiceAdapter {
+
+        @Override
+        public boolean isAvailable(DeviceId deviceId) {
+            return true;
+        }
+
+        @Override
+        public void addListener(DeviceListener listener) {
+            SingleSwitchFibInstallerTest.this.deviceListener = listener;
+        }
+    }
+}
