diff --git a/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java b/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
new file mode 100644
index 0000000..063517e
--- /dev/null
+++ b/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
@@ -0,0 +1,402 @@
+/*
+ * 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.segmentrouting;
+
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+
+import org.onlab.packet.MplsLabel;
+import org.onosproject.grouphandler.NeighborSet;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.PortNumber;
+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.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.group.DefaultGroupKey;
+import org.onosproject.net.group.Group;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+public class RoutingRulePopulator {
+
+    private static final Logger log = LoggerFactory.getLogger(RoutingRulePopulator.class);
+
+    private SegmentRoutingManager srManager;
+    private NetworkConfigHandler config;
+
+    /**
+     * Creates a RoutingRulePopulator object.
+     *
+     * @param srManager
+     */
+    public RoutingRulePopulator(SegmentRoutingManager srManager) {
+        this.srManager = srManager;
+        this.config = checkNotNull(srManager.networkConfigHandler);
+    }
+
+    /**
+     * Populates IP flow rules for specific hosts directly connected to the switch.
+     *
+     * @param deviceId switch ID to set the rules
+     * @param hostIp host IP address
+     * @param hostMac host MAC address
+     * @param outPort port where the host is connected
+     */
+    public void populateIpRuleForHost(DeviceId deviceId, Ip4Address hostIp,
+                                      MacAddress hostMac, PortNumber outPort) {
+        TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
+        TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
+
+        sbuilder.matchIPDst(IpPrefix.valueOf(hostIp, 32));
+        sbuilder.matchEthType(Ethernet.TYPE_IPV4);
+
+        tbuilder.setEthDst(hostMac)
+                .setEthSrc(config.getRouterMacAddress(deviceId))
+                .setOutput(outPort);
+
+        TrafficTreatment treatment = tbuilder.build();
+        TrafficSelector selector = sbuilder.build();
+
+        FlowRule f = new DefaultFlowRule(deviceId, selector, treatment, 100,
+                srManager.appId, 600, false, FlowRule.Type.IP);
+
+        srManager.flowRuleService.applyFlowRules(f);
+        log.debug("Flow rule {} is set to switch {}", f, deviceId);
+    }
+
+    /**
+     * Populates IP flow rules for the subnets of the destination router.
+     *
+     * @param deviceId switch ID to set the rules
+     * @param subnetInfo subnet information
+     * @param destSw destination switch ID
+     * @param nextHops next hop switch ID list
+     * @return true if all rules are set successfully, false otherwise
+     */
+    public boolean populateIpRuleForSubnet(DeviceId deviceId, String subnetInfo,
+                                           DeviceId destSw, Set<DeviceId> nextHops) {
+
+        List<IpPrefix> subnets = extractSubnet(subnetInfo);
+        for (IpPrefix subnet: subnets) {
+            if (!populateIpRuleForRouter(deviceId, subnet, destSw, nextHops)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Populates IP flow rules for the router IP address.
+     *
+     * @param deviceId device ID to set the rules
+     * @param ipPrefix the IP address of the destination router
+     * @param destSw device ID of the destination router
+     * @param nextHops next hop switch ID list
+     * @return true if all rules are set successfully, false otherwise
+     */
+    public boolean populateIpRuleForRouter(DeviceId deviceId, IpPrefix ipPrefix,
+                                           DeviceId destSw, Set<DeviceId> nextHops) {
+
+        TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
+        TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
+
+        sbuilder.matchIPDst(ipPrefix);
+        sbuilder.matchEthType(Ethernet.TYPE_IPV4);
+
+        NeighborSet ns = null;
+
+        //If the next hop is the same as the final destination, then MPLS label is not set.
+        if (nextHops.size() == 1 && nextHops.toArray()[0].equals(destSw)) {
+            tbuilder.decNwTtl();
+            ns = new NeighborSet(nextHops);
+        } else {
+            tbuilder.copyTtlOut();
+            ns = new NeighborSet(nextHops, config.getMplsId(destSw));
+        }
+
+        DefaultGroupKey groupKey = (DefaultGroupKey) srManager.getGroupKey(ns);
+        if (groupKey == null) {
+            log.warn("Group key is not found for ns {}", ns);
+            return false;
+        }
+        Group group = srManager.groupService.getGroup(deviceId, groupKey);
+        if (group != null) {
+            tbuilder.group(group.id());
+        } else {
+            log.warn("No group found for NeighborSet {} from {} to {}",
+                    ns, deviceId, destSw);
+            return false;
+        }
+
+        TrafficTreatment treatment = tbuilder.build();
+        TrafficSelector selector = sbuilder.build();
+
+        FlowRule f = new DefaultFlowRule(deviceId, selector, treatment, 100,
+                srManager.appId, 600, false, FlowRule.Type.IP);
+
+        srManager.flowRuleService.applyFlowRules(f);
+        log.debug("IP flow rule {} is set to switch {}", f, deviceId);
+
+        return true;
+    }
+
+
+    /**
+     * Populates MPLS flow rules to all transit routers.
+     *
+     * @param deviceId device ID of the switch to set the rules
+     * @param destSwId destination switch device ID
+     * @param nextHops next hops switch ID list
+     * @return true if all rules are set successfully, false otherwise
+     */
+    public boolean populateMplsRule(DeviceId deviceId, DeviceId destSwId, Set<DeviceId> nextHops) {
+
+        TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
+        Collection<TrafficTreatment> treatments = new ArrayList<>();
+
+        // TODO Handle the case of Bos == false
+        sbuilder.matchMplsLabel(MplsLabel.mplsLabel(config.getMplsId(destSwId)));
+        sbuilder.matchEthType(Ethernet.MPLS_UNICAST);
+
+        //If the next hop is the destination router, do PHP
+        if (nextHops.size() == 1 && destSwId.equals(nextHops.toArray()[0])) {
+            TrafficTreatment treatmentBos =
+                    getMplsTreatment(deviceId, destSwId, nextHops, true, true);
+            TrafficTreatment treatment =
+                    getMplsTreatment(deviceId, destSwId, nextHops, true, false);
+            if (treatmentBos != null) {
+                treatments.add(treatmentBos);
+            } else {
+                log.warn("Failed to set MPLS rules.");
+                return false;
+            }
+        } else {
+            TrafficTreatment treatmentBos =
+                    getMplsTreatment(deviceId, destSwId, nextHops, false, true);
+            TrafficTreatment treatment =
+                    getMplsTreatment(deviceId, destSwId, nextHops, false, false);
+
+            if (treatmentBos != null) {
+                treatments.add(treatmentBos);
+            } else {
+                log.warn("Failed to set MPLS rules.");
+                return false;
+            }
+        }
+
+        TrafficSelector selector = sbuilder.build();
+        for (TrafficTreatment treatment: treatments) {
+            FlowRule f = new DefaultFlowRule(deviceId, selector, treatment, 100,
+                    srManager.appId, 600, false, FlowRule.Type.MPLS);
+            srManager.flowRuleService.applyFlowRules(f);
+            log.debug("MPLS rule {} is set to {}", f, deviceId);
+        }
+
+        return true;
+    }
+
+
+    private TrafficTreatment getMplsTreatment(DeviceId deviceId, DeviceId destSw,
+                                             Set<DeviceId> nextHops,
+                                             boolean phpRequired, boolean isBos) {
+
+        TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
+
+        if (phpRequired) {
+            tbuilder.copyTtlIn();
+            if (isBos) {
+                tbuilder.popMpls(Ethernet.TYPE_IPV4)
+                        .decNwTtl();
+            } else {
+                tbuilder.popMpls(Ethernet.MPLS_UNICAST)
+                .decMplsTtl();
+            }
+        } else {
+            tbuilder.decMplsTtl();
+        }
+
+        if (config.isEcmpNotSupportedInTransit(deviceId)
+                && config.isTransitRouter(deviceId)) {
+            Link link = selectOneLink(deviceId, nextHops);
+            if (link == null) {
+                log.warn("No link from {} to {}", deviceId, nextHops);
+                return null;
+            }
+            tbuilder.setEthSrc(config.getRouterMacAddress(deviceId))
+                    .setEthDst(config.getRouterMacAddress(link.dst().deviceId()))
+                    .setOutput(link.src().port());
+        } else {
+            NeighborSet ns = new NeighborSet(nextHops);
+            DefaultGroupKey groupKey = (DefaultGroupKey) srManager.getGroupKey(ns);
+            if (groupKey == null) {
+                log.warn("Group key is not found for ns {}", ns);
+                return null;
+            }
+            Group group = srManager.groupService.getGroup(deviceId, groupKey);
+            if (group != null) {
+                tbuilder.group(group.id());
+            } else {
+                log.warn("No group found for ns {} key {} in {}", ns,
+                        srManager.getGroupKey(ns), deviceId);
+                return null;
+            }
+        }
+
+        return tbuilder.build();
+    }
+
+    /**
+     * Populates VLAN flows rules.
+     * All packets are forwarded to TMAC table.
+     *
+     * @param deviceId switch ID to set the rules
+     */
+    public void populateTableVlan(DeviceId deviceId) {
+        TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
+        TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
+
+        tbuilder.transition(FlowRule.Type.ETHER);
+
+        TrafficTreatment treatment = tbuilder.build();
+        TrafficSelector selector = sbuilder.build();
+
+        FlowRule f = new DefaultFlowRule(deviceId, selector, treatment, 100,
+                srManager.appId, 600, false, FlowRule.Type.VLAN);
+
+        srManager.flowRuleService.applyFlowRules(f);
+
+        log.debug("Vlan flow rule {} is set to switch {}", f, deviceId);
+    }
+
+    /**
+     * Populates TMAC table rules.
+     * IP packets are forwarded to IP table.
+     * MPLS packets are forwarded to MPLS table.
+     *
+     * @param deviceId switch ID to set the rules
+     */
+    public void populateTableTMac(DeviceId deviceId) {
+
+        // flow rule for IP packets
+        TrafficSelector selectorIp = DefaultTrafficSelector.builder()
+                .matchEthType(Ethernet.TYPE_IPV4)
+                .matchEthDst(config.getRouterMacAddress(deviceId))
+                .build();
+        TrafficTreatment treatmentIp = DefaultTrafficTreatment.builder()
+                .transition(FlowRule.Type.IP)
+                .build();
+
+        FlowRule flowIp = new DefaultFlowRule(deviceId, selectorIp, treatmentIp, 100,
+                srManager.appId, 600, false, FlowRule.Type.ETHER);
+
+        srManager.flowRuleService.applyFlowRules(flowIp);
+
+        // flow rule for MPLS packets
+        TrafficSelector selectorMpls = DefaultTrafficSelector.builder()
+                .matchEthType(Ethernet.MPLS_UNICAST)
+                .matchEthDst(config.getRouterMacAddress(deviceId))
+                .build();
+        TrafficTreatment treatmentMpls = DefaultTrafficTreatment.builder()
+                .transition(FlowRule.Type.MPLS)
+                .build();
+
+        FlowRule flowMpls = new DefaultFlowRule(deviceId, selectorMpls, treatmentMpls, 100,
+                srManager.appId, 600, false, FlowRule.Type.ETHER);
+
+        srManager.flowRuleService.applyFlowRules(flowMpls);
+
+    }
+
+    /**
+     * Populates a table miss entry.
+     *
+     * @param deviceId switch ID to set rules
+     * @param tableToAdd table to set the rules
+     * @param toControllerNow flag to send packets to controller immediately
+     * @param toControllerWrite flag to send packets to controller at the end of pipeline
+     * @param toTable flag to send packets to a specific table
+     * @param tableToSend table type to send packets when the toTable flag is set
+     */
+    public void populateTableMissEntry(DeviceId deviceId, FlowRule.Type tableToAdd, boolean toControllerNow,
+                                       boolean toControllerWrite,
+                                       boolean toTable, FlowRule.Type tableToSend) {
+        // TODO: Change arguments to EnumSet
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .build();
+        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+
+        if (toControllerNow) {
+            tBuilder.setOutput(PortNumber.CONTROLLER);
+        }
+
+        if (toControllerWrite) {
+            tBuilder.deferred().setOutput(PortNumber.CONTROLLER);
+        }
+
+        if (toTable) {
+            tBuilder.transition(tableToSend);
+        }
+
+        FlowRule flow = new DefaultFlowRule(deviceId, selector, tBuilder.build(), 0,
+                srManager.appId, 600, false, tableToAdd);
+
+        srManager.flowRuleService.applyFlowRules(flow);
+
+    }
+
+
+    private List<IpPrefix> extractSubnet(String subnetInfo) {
+        List<IpPrefix> subnetIpPrefixes = new ArrayList<>();
+
+        // TODO: refactoring required depending on the format of the subnet info
+        IpPrefix prefix = IpPrefix.valueOf(subnetInfo);
+        if (prefix == null) {
+            log.error("Wrong ip prefix type {}", subnetInfo);
+        } else {
+            subnetIpPrefixes.add(prefix);
+        }
+
+        return subnetIpPrefixes;
+    }
+
+    private Link selectOneLink(DeviceId srcId, Set<DeviceId> destIds) {
+
+        Set<Link> links = srManager.linkService.getDeviceEgressLinks(srcId);
+        DeviceId destId = (DeviceId) destIds.toArray()[0];
+        for (Link link: links) {
+            if (link.dst().deviceId().equals(destId)) {
+                return link;
+            }
+        }
+
+        return null;
+    }
+
+}
