diff --git a/core/net/src/main/java/org/onosproject/net/host/impl/HostManager.java b/core/net/src/main/java/org/onosproject/net/host/impl/HostManager.java
index 183a0ba..cda9e04 100644
--- a/core/net/src/main/java/org/onosproject/net/host/impl/HostManager.java
+++ b/core/net/src/main/java/org/onosproject/net/host/impl/HostManager.java
@@ -29,7 +29,7 @@
 import org.onlab.packet.VlanId;
 import org.onlab.util.Tools;
 import org.onosproject.cfg.ComponentConfigService;
-import org.onosproject.incubator.net.intf.InterfaceService;
+import org.onosproject.net.intf.InterfaceService;
 import org.onosproject.net.HostLocation;
 import org.onosproject.net.edge.EdgePortService;
 import org.onosproject.net.provider.AbstractListenerProviderRegistry;
diff --git a/core/net/src/main/java/org/onosproject/net/host/impl/HostMonitor.java b/core/net/src/main/java/org/onosproject/net/host/impl/HostMonitor.java
index 52829ba..950bedd 100644
--- a/core/net/src/main/java/org/onosproject/net/host/impl/HostMonitor.java
+++ b/core/net/src/main/java/org/onosproject/net/host/impl/HostMonitor.java
@@ -23,7 +23,7 @@
 import org.onlab.packet.VlanId;
 import org.onlab.packet.ndp.NeighborSolicitation;
 import org.onlab.util.SharedScheduledExecutors;
-import org.onosproject.incubator.net.intf.InterfaceService;
+import org.onosproject.net.intf.InterfaceService;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.Host;
 import org.onosproject.net.edge.EdgePortService;
diff --git a/core/net/src/main/java/org/onosproject/net/intf/impl/InterfaceManager.java b/core/net/src/main/java/org/onosproject/net/intf/impl/InterfaceManager.java
new file mode 100644
index 0000000..5693db5
--- /dev/null
+++ b/core/net/src/main/java/org/onosproject/net/intf/impl/InterfaceManager.java
@@ -0,0 +1,267 @@
+/*
+ * Copyright 2015-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.intf.impl;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+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.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.event.ListenerRegistry;
+import org.onosproject.incubator.net.config.basics.ConfigException;
+import org.onosproject.incubator.net.config.basics.InterfaceConfig;
+import org.onosproject.net.intf.Interface;
+import org.onosproject.net.intf.InterfaceAdminService;
+import org.onosproject.net.intf.InterfaceEvent;
+import org.onosproject.net.intf.InterfaceListener;
+import org.onosproject.net.intf.InterfaceService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.config.NetworkConfigService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Stream;
+
+import static java.util.stream.Collectors.collectingAndThen;
+import static java.util.stream.Collectors.toSet;
+
+/**
+ * Manages the inventory of interfaces in the system.
+ */
+@Service
+@Component(immediate = true)
+public class InterfaceManager extends ListenerRegistry<InterfaceEvent, InterfaceListener>
+        implements InterfaceService, InterfaceAdminService {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    private static final Class<ConnectPoint> SUBJECT_CLASS = ConnectPoint.class;
+    private static final Class<InterfaceConfig> CONFIG_CLASS = InterfaceConfig.class;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigService configService;
+
+    private final InternalConfigListener listener = new InternalConfigListener();
+
+    private final Map<ConnectPoint, Set<Interface>> interfaces = Maps.newConcurrentMap();
+
+    @Activate
+    public void activate() {
+        configService.addListener(listener);
+
+        // TODO address concurrency issues here
+        for (ConnectPoint subject : configService.getSubjects(SUBJECT_CLASS, CONFIG_CLASS)) {
+            InterfaceConfig config = configService.getConfig(subject, CONFIG_CLASS);
+
+            if (config != null) {
+                updateInterfaces(config);
+            }
+        }
+
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        configService.removeListener(listener);
+
+        log.info("Stopped");
+    }
+
+    @Override
+    public Set<Interface> getInterfaces() {
+        return interfaces.values()
+                .stream()
+                .flatMap(set -> set.stream())
+                .collect(collectingAndThen(toSet(), ImmutableSet::copyOf));
+    }
+
+    @Override
+    public Interface getInterfaceByName(ConnectPoint connectPoint, String name) {
+        Optional<Interface> intf =
+                interfaces.getOrDefault(connectPoint, Collections.emptySet())
+                .stream()
+                .filter(i -> i.name().equals(name))
+                .findAny();
+
+        return intf.orElse(null);
+    }
+
+    @Override
+    public Set<Interface> getInterfacesByPort(ConnectPoint port) {
+        Set<Interface> intfs = interfaces.get(port);
+        if (intfs == null) {
+            return Collections.emptySet();
+        }
+        return ImmutableSet.copyOf(intfs);
+    }
+
+    @Override
+    public Set<Interface> getInterfacesByIp(IpAddress ip) {
+        return interfaces.values()
+                .stream()
+                .flatMap(Collection::stream)
+                .filter(intf -> intf.ipAddressesList()
+                        .stream()
+                        .anyMatch(ia -> ia.ipAddress().equals(ip)))
+                .collect(collectingAndThen(toSet(), ImmutableSet::copyOf));
+    }
+
+    @Override
+    public Interface getMatchingInterface(IpAddress ip) {
+        return getMatchingInterfacesStream(ip).findFirst().orElse(null);
+    }
+
+    @Override
+    public Set<Interface> getMatchingInterfaces(IpAddress ip) {
+        return getMatchingInterfacesStream(ip).collect(toSet());
+    }
+
+    private Stream<Interface> getMatchingInterfacesStream(IpAddress ip) {
+        return interfaces.values()
+                .stream()
+                .flatMap(Collection::stream)
+                .filter(intf -> intf.ipAddressesList()
+                        .stream()
+                        .anyMatch(intfIp -> intfIp.subnetAddress().contains(ip)));
+    }
+
+    @Override
+    public Set<Interface> getInterfacesByVlan(VlanId vlan) {
+        return interfaces.values()
+                .stream()
+                .flatMap(Collection::stream)
+                .filter(intf -> intf.vlan().equals(vlan))
+                .collect(collectingAndThen(toSet(), ImmutableSet::copyOf));
+    }
+
+    private void updateInterfaces(InterfaceConfig intfConfig) {
+        try {
+            Set<Interface> old = interfaces.put(intfConfig.subject(),
+                    Sets.newHashSet(intfConfig.getInterfaces()));
+
+            if (old == null) {
+                old = Collections.emptySet();
+            }
+
+            for (Interface intf : intfConfig.getInterfaces()) {
+                if (intf.name().equals(Interface.NO_INTERFACE_NAME)) {
+                    process(new InterfaceEvent(InterfaceEvent.Type.INTERFACE_ADDED, intf));
+                } else {
+                    Optional<Interface> oldIntf = findInterface(intf, old);
+                    if (oldIntf.isPresent()) {
+                        old.remove(oldIntf.get());
+                        if (!oldIntf.get().equals(intf)) {
+                            process(new InterfaceEvent(InterfaceEvent.Type.INTERFACE_UPDATED, intf, oldIntf.get()));
+                        }
+                    } else {
+                        process(new InterfaceEvent(InterfaceEvent.Type.INTERFACE_ADDED, intf));
+                    }
+                }
+            }
+
+            for (Interface intf : old) {
+                if (!intf.name().equals(Interface.NO_INTERFACE_NAME)) {
+                    process(new InterfaceEvent(InterfaceEvent.Type.INTERFACE_REMOVED, intf));
+                }
+            }
+        } catch (ConfigException e) {
+            log.error("Error in interface config", e);
+        }
+    }
+
+    private Optional<Interface> findInterface(Interface intf, Set<Interface> set) {
+        return set.stream().filter(i -> i.name().equals(intf.name())).findAny();
+    }
+
+    private void removeInterfaces(ConnectPoint port) {
+        Set<Interface> old = interfaces.remove(port);
+
+        old.stream()
+                .filter(i -> !i.name().equals(Interface.NO_INTERFACE_NAME))
+                .forEach(i -> process(new InterfaceEvent(InterfaceEvent.Type.INTERFACE_REMOVED, i)));
+    }
+
+    @Override
+    public void add(Interface intf) {
+        InterfaceConfig config =
+                configService.addConfig(intf.connectPoint(), CONFIG_CLASS);
+
+        config.addInterface(intf);
+
+        configService.applyConfig(intf.connectPoint(), CONFIG_CLASS, config.node());
+    }
+
+    @Override
+    public boolean remove(ConnectPoint connectPoint, String name) {
+        InterfaceConfig config = configService.addConfig(connectPoint, CONFIG_CLASS);
+        config.removeInterface(name);
+
+        try {
+            if (config.getInterfaces().isEmpty()) {
+                configService.removeConfig(connectPoint, CONFIG_CLASS);
+            } else {
+                configService.applyConfig(connectPoint, CONFIG_CLASS, config.node());
+            }
+        } catch (ConfigException e) {
+            log.error("Error reading interfaces JSON", e);
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Listener for network config events.
+     */
+    private class InternalConfigListener implements NetworkConfigListener {
+
+        @Override
+        public void event(NetworkConfigEvent event) {
+            if (event.configClass() == CONFIG_CLASS) {
+                switch (event.type()) {
+                case CONFIG_ADDED:
+                case CONFIG_UPDATED:
+                    InterfaceConfig config =
+                            configService.getConfig((ConnectPoint) event.subject(), InterfaceConfig.class);
+                    updateInterfaces(config);
+                    break;
+                case CONFIG_REMOVED:
+                    removeInterfaces((ConnectPoint) event.subject());
+                    break;
+                case CONFIG_REGISTERED:
+                case CONFIG_UNREGISTERED:
+                default:
+                    break;
+                }
+            }
+        }
+    }
+}
diff --git a/core/net/src/main/java/org/onosproject/net/intf/impl/package-info.java b/core/net/src/main/java/org/onosproject/net/intf/impl/package-info.java
new file mode 100644
index 0000000..e5884c5
--- /dev/null
+++ b/core/net/src/main/java/org/onosproject/net/intf/impl/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2015-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Implementation of service for interacting with interfaces.
+ */
+package org.onosproject.net.impl;
diff --git a/core/net/src/test/java/org/onosproject/net/host/impl/HostMonitorTest.java b/core/net/src/test/java/org/onosproject/net/host/impl/HostMonitorTest.java
index 473c720..37ae0d3 100644
--- a/core/net/src/test/java/org/onosproject/net/host/impl/HostMonitorTest.java
+++ b/core/net/src/test/java/org/onosproject/net/host/impl/HostMonitorTest.java
@@ -29,8 +29,8 @@
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.VlanId;
 import org.onlab.packet.ndp.NeighborSolicitation;
-import org.onosproject.incubator.net.intf.Interface;
-import org.onosproject.incubator.net.intf.InterfaceService;
+import org.onosproject.net.intf.Interface;
+import org.onosproject.net.intf.InterfaceService;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.Device;
 import org.onosproject.net.DeviceId;
diff --git a/core/net/src/test/java/org/onosproject/net/intf/impl/InterfaceManagerTest.java b/core/net/src/test/java/org/onosproject/net/intf/impl/InterfaceManagerTest.java
new file mode 100644
index 0000000..89ca4ee
--- /dev/null
+++ b/core/net/src/test/java/org/onosproject/net/intf/impl/InterfaceManagerTest.java
@@ -0,0 +1,289 @@
+/*
+ * Copyright 2015-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.intf.impl;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.incubator.net.config.basics.ConfigException;
+import org.onosproject.incubator.net.config.basics.InterfaceConfig;
+import org.onosproject.net.intf.Interface;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.config.Config;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.config.NetworkConfigServiceAdapter;
+import org.onosproject.net.host.InterfaceIpAddress;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static junit.framework.TestCase.assertEquals;
+import static org.junit.Assert.assertNull;
+
+/**
+ * Unit tests for InterfaceManager.
+ */
+public class InterfaceManagerTest {
+    private static final Class<InterfaceConfig> CONFIG_CLASS = InterfaceConfig.class;
+
+    private static final int NUM_INTERFACES = 4;
+
+    private Set<ConnectPoint> subjects = Sets.newHashSet();
+    private Map<ConnectPoint, InterfaceConfig> configs = Maps.newHashMap();
+
+    private Set<Interface> interfaces = Sets.newHashSet();
+
+    private NetworkConfigListener listener;
+
+    private InterfaceManager interfaceManager;
+
+    @Before
+    public void setUp() throws Exception {
+        for (int i = 0; i < NUM_INTERFACES; i++) {
+            ConnectPoint cp = createConnectPoint(i);
+            subjects.add(cp);
+
+            Interface intf = createInterface(i);
+
+            interfaces.add(intf);
+
+            InterfaceConfig ic = new TestInterfaceConfig(cp, Sets.newHashSet(intf));
+
+            configs.put(cp, ic);
+        }
+
+        TestNetworkConfigService configService =
+                new TestNetworkConfigService(subjects, configs);
+
+        interfaceManager = new InterfaceManager();
+        interfaceManager.configService = configService;
+        interfaceManager.activate();
+    }
+
+    private Interface createInterface(int i) {
+        ConnectPoint cp = createConnectPoint(i);
+
+        InterfaceIpAddress ia = InterfaceIpAddress.valueOf("192.168." + i + ".1/24");
+
+        Interface intf = new Interface(Interface.NO_INTERFACE_NAME, cp,
+                Collections.singletonList(ia),
+                MacAddress.valueOf(i),
+                VlanId.vlanId((short) i));
+
+        return intf;
+    }
+
+    private ConnectPoint createConnectPoint(int i) {
+        return  ConnectPoint.deviceConnectPoint("of:000000000000000" + i + "/1");
+    }
+
+    @Test
+    public void testGetInterfaces() throws Exception {
+        assertEquals(interfaces, interfaceManager.getInterfaces());
+    }
+
+    @Test
+    public void testGetInterfacesByPort() throws Exception {
+        ConnectPoint cp = ConnectPoint.deviceConnectPoint("of:0000000000000001/1");
+
+        Set<Interface> byPort = Collections.singleton(createInterface(1));
+
+        assertEquals(byPort, interfaceManager.getInterfacesByPort(cp));
+    }
+
+    @Test
+    public void testGetInterfacesByIp() throws Exception {
+        IpAddress ip = Ip4Address.valueOf("192.168.2.1");
+
+        Set<Interface> byIp = Collections.singleton(createInterface(2));
+
+        assertEquals(byIp, interfaceManager.getInterfacesByIp(ip));
+    }
+
+    @Test
+    public void testGetMatchingInterface() throws Exception {
+        IpAddress ip = Ip4Address.valueOf("192.168.1.100");
+
+        Interface matchingIntf = createInterface(1);
+
+        assertEquals(matchingIntf, interfaceManager.getMatchingInterface(ip));
+
+        // Searching for an IP with no match should return null
+        ip = Ip4Address.valueOf("1.1.1.1");
+
+        assertNull(interfaceManager.getMatchingInterface(ip));
+    }
+
+    @Test
+    public void testGetInterfacesByVlan() throws Exception {
+        VlanId vlanId = VlanId.vlanId((short) 1);
+
+        Set<Interface> byVlan = Collections.singleton(createInterface(1));
+
+        assertEquals(byVlan, interfaceManager.getInterfacesByVlan(vlanId));
+    }
+
+    @Test
+    public void testAddInterface() throws Exception {
+        // Create a new InterfaceConfig which will get added
+        VlanId vlanId = VlanId.vlanId((short) 1);
+        ConnectPoint cp = ConnectPoint.deviceConnectPoint("of:0000000000000001/2");
+        Interface newIntf = new Interface(Interface.NO_INTERFACE_NAME, cp,
+                Collections.emptyList(),
+                MacAddress.valueOf(100),
+                vlanId);
+
+        InterfaceConfig ic = new TestInterfaceConfig(cp, Collections.singleton(newIntf));
+
+        subjects.add(cp);
+        configs.put(cp, ic);
+        interfaces.add(newIntf);
+
+        NetworkConfigEvent event = new NetworkConfigEvent(
+                NetworkConfigEvent.Type.CONFIG_ADDED, cp, CONFIG_CLASS);
+
+        assertEquals(NUM_INTERFACES, interfaceManager.getInterfaces().size());
+
+        // Send in a config event containing a new interface config
+        listener.event(event);
+
+        // Check the new interface exists in the InterfaceManager's inventory
+        assertEquals(interfaces, interfaceManager.getInterfaces());
+        assertEquals(NUM_INTERFACES + 1, interfaceManager.getInterfaces().size());
+
+        // There are now two interfaces with vlan ID 1
+        Set<Interface> byVlan = Sets.newHashSet(createInterface(1), newIntf);
+        assertEquals(byVlan, interfaceManager.getInterfacesByVlan(vlanId));
+    }
+
+    @Test
+    public void testUpdateInterface() throws Exception {
+        ConnectPoint cp = createConnectPoint(1);
+
+        // Create an interface that is the same as the existing one, but adds a
+        // new IP address
+        Interface intf = createInterface(1);
+        List<InterfaceIpAddress> addresses = Lists.newArrayList(intf.ipAddressesList());
+        addresses.add(InterfaceIpAddress.valueOf("192.168.100.1/24"));
+        intf = new Interface(Interface.NO_INTERFACE_NAME, intf.connectPoint(), addresses, intf.mac(), intf.vlan());
+
+        // Create a new interface on the same connect point as the existing one
+        InterfaceIpAddress newAddr = InterfaceIpAddress.valueOf("192.168.101.1/24");
+        Interface newIntf = new Interface(Interface.NO_INTERFACE_NAME, cp,
+                Collections.singletonList(newAddr),
+                MacAddress.valueOf(101),
+                VlanId.vlanId((short) 101));
+
+        Set<Interface> interfaces = Sets.newHashSet(intf, newIntf);
+
+        // New interface config updates the existing interface and adds a new
+        // interface to the same connect point
+        InterfaceConfig ic = new TestInterfaceConfig(cp, interfaces);
+
+        configs.put(cp, ic);
+
+        NetworkConfigEvent event = new NetworkConfigEvent(
+                NetworkConfigEvent.Type.CONFIG_UPDATED, cp, CONFIG_CLASS);
+
+        // Send in the event signalling the interfaces for this connect point
+        // have been updated
+        listener.event(event);
+
+        assertEquals(NUM_INTERFACES + 1, interfaceManager.getInterfaces().size());
+        assertEquals(interfaces, interfaceManager.getInterfacesByPort(cp));
+    }
+
+    @Test
+    public void testRemoveInterface() throws Exception {
+        ConnectPoint cp = createConnectPoint(1);
+
+        NetworkConfigEvent event = new NetworkConfigEvent(
+                NetworkConfigEvent.Type.CONFIG_REMOVED, cp, CONFIG_CLASS);
+
+        assertEquals(NUM_INTERFACES, interfaceManager.getInterfaces().size());
+
+        // Send in a config event removing an interface config
+        listener.event(event);
+
+        assertEquals(NUM_INTERFACES - 1, interfaceManager.getInterfaces().size());
+    }
+
+    /**
+     * Test version of NetworkConfigService which allows us to pass in subjects
+     * and InterfaceConfigs directly.
+     */
+    private class TestNetworkConfigService extends NetworkConfigServiceAdapter {
+        private final Set<ConnectPoint> subjects;
+        private final Map<ConnectPoint, InterfaceConfig> configs;
+
+        public TestNetworkConfigService(Set<ConnectPoint> subjects,
+                                        Map<ConnectPoint, InterfaceConfig> configs) {
+            this.subjects = subjects;
+            this.configs = configs;
+        }
+
+        @Override
+        public <S, C extends Config<S>> Set<S> getSubjects(Class<S> subjectClass,
+                                                           Class<C> configClass) {
+            return (Set<S>) subjects;
+        }
+
+        @Override
+        public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) {
+            return (C) configs.get(subject);
+        }
+
+        @Override
+        public void addListener(NetworkConfigListener listener) {
+            InterfaceManagerTest.this.listener = listener;
+        }
+    }
+
+    /**
+     * Test version of InterfaceConfig where we can inject interfaces directly,
+     * rather than parsing them from JSON.
+     */
+    private class TestInterfaceConfig extends InterfaceConfig {
+        private final ConnectPoint subject;
+        private final Set<Interface> interfaces;
+
+        @Override
+        public ConnectPoint subject() {
+            return subject;
+        }
+
+        public TestInterfaceConfig(ConnectPoint subject, Set<Interface> interfaces) {
+            this.subject = subject;
+            this.interfaces = interfaces;
+        }
+
+        @Override
+        public Set<Interface> getInterfaces() throws ConfigException {
+            return interfaces;
+        }
+    }
+
+}
