diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/installer/FlowRuleIntentInstaller.java b/core/net/src/main/java/org/onosproject/net/intent/impl/installer/FlowRuleIntentInstaller.java
new file mode 100644
index 0000000..f29ceec
--- /dev/null
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/installer/FlowRuleIntentInstaller.java
@@ -0,0 +1,207 @@
+/*
+ * 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.net.intent.impl.installer;
+
+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.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.FlowRuleOperations;
+import org.onosproject.net.flow.FlowRuleOperationsContext;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.intent.FlowRuleIntent;
+import org.onosproject.net.intent.IntentInstallCoordinator;
+import org.onosproject.net.intent.IntentData;
+import org.onosproject.net.intent.IntentExtensionService;
+import org.onosproject.net.intent.IntentOperationContext;
+import org.onosproject.net.intent.IntentInstaller;
+import org.onosproject.net.intent.impl.IntentManager;
+import org.onosproject.net.intent.impl.ObjectiveTrackerService;
+import org.slf4j.Logger;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import static org.onosproject.net.intent.IntentInstaller.Direction.ADD;
+import static org.onosproject.net.intent.IntentInstaller.Direction.REMOVE;
+import static org.onosproject.net.intent.IntentState.INSTALLED;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Installer for FlowRuleIntent.
+ */
+@Component(immediate = true)
+public class FlowRuleIntentInstaller implements IntentInstaller<FlowRuleIntent> {
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected IntentExtensionService intentExtensionService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ObjectiveTrackerService trackerService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected IntentInstallCoordinator intentInstallCoordinator;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected FlowRuleService flowRuleService;
+
+    @Activate
+    public void activate() {
+        intentExtensionService.registerInstaller(FlowRuleIntent.class, this);
+    }
+
+    @Deactivate
+    public void deactivated() {
+        intentExtensionService.unregisterInstaller(FlowRuleIntent.class);
+    }
+
+    protected final Logger log = getLogger(IntentManager.class);
+
+    @Override
+    public void apply(IntentOperationContext<FlowRuleIntent> context) {
+        Optional<IntentData> toUninstall = context.toUninstall();
+        Optional<IntentData> toInstall = context.toInstall();
+
+        List<FlowRuleIntent> uninstallIntents = context.intentsToUninstall();
+        List<FlowRuleIntent> installIntents = context.intentsToInstall();
+
+        if (!toInstall.isPresent() && !toUninstall.isPresent()) {
+            intentInstallCoordinator.intentInstallSuccess(context);
+            return;
+        } else if (!toInstall.isPresent()) {
+            // Uninstall only
+            trackIntentResources(toUninstall.get(), uninstallIntents, REMOVE);
+        } else if (!toUninstall.isPresent()) {
+            // Install only
+            trackIntentResources(toInstall.get(), installIntents, ADD);
+        } else {
+            IntentData uninstall = toUninstall.get();
+            IntentData install = toInstall.get();
+
+            // Filter out same intents and intents with same flow rules
+            Iterator<FlowRuleIntent> iterator = installIntents.iterator();
+            while (iterator.hasNext()) {
+                FlowRuleIntent installIntent = iterator.next();
+                uninstallIntents.stream().filter(uIntent -> {
+                    if (uIntent.equals(installIntent)) {
+                        return true;
+                    } else {
+                        return !flowRuleIntentChanged(uIntent, installIntent);
+                    }
+                }).findFirst().ifPresent(common -> {
+                    uninstallIntents.remove(common);
+                    if (INSTALLED.equals(uninstall.state())) {
+                        // only remove the install intent if the existing
+                        // intent (i.e. the uninstall one) is already
+                        // installed or installing
+                        iterator.remove();
+                    }
+                });
+            }
+            trackIntentResources(uninstall, uninstallIntents, REMOVE);
+            trackIntentResources(install, installIntents, ADD);
+        }
+
+        FlowRuleOperations.Builder builder = FlowRuleOperations.builder();
+        builder.newStage();
+
+        toUninstall.ifPresent(intentData -> {
+            uninstallIntents.stream().map(FlowRuleIntent::flowRules)
+                    .flatMap(Collection::stream).forEach(builder::remove);
+        });
+
+        toInstall.ifPresent(intentData -> {
+            installIntents.stream().map(FlowRuleIntent::flowRules)
+                    .flatMap(Collection::stream).forEach(builder::add);
+        });
+
+        FlowRuleOperationsContext flowRuleOperationsContext = new FlowRuleOperationsContext() {
+            @Override
+            public void onSuccess(FlowRuleOperations ops) {
+                intentInstallCoordinator.intentInstallSuccess(context);
+            }
+
+            @Override
+            public void onError(FlowRuleOperations ops) {
+                intentInstallCoordinator.intentInstallFailed(context);
+            }
+        };
+
+        FlowRuleOperations operations = builder.build(flowRuleOperationsContext);
+
+
+        log.debug("applying intent {} -> {} with {} rules: {}",
+                  toUninstall.map(x -> x.key().toString()).orElse("<empty>"),
+                  toInstall.map(x -> x.key().toString()).orElse("<empty>"),
+                  operations.stages().stream().mapToLong(Set::size).sum(),
+                  operations.stages());
+        flowRuleService.apply(operations);
+    }
+
+    /**
+     * Track or un-track network resource of a Intent and it's installable
+     * Intents.
+     *
+     * @param intentData the Intent data
+     * @param intentsToApply the list of flow rule Intents from the Intent
+     * @param direction the direction to determine track or un-track
+     */
+    private void trackIntentResources(IntentData intentData, List<FlowRuleIntent> intentsToApply, Direction direction) {
+        switch (direction) {
+            case ADD:
+                trackerService.addTrackedResources(intentData.key(), intentData.intent().resources());
+                intentsToApply.forEach(installable ->
+                                               trackerService.addTrackedResources(intentData.key(),
+                                                                                  installable.resources()));
+                break;
+            default:
+                trackerService.removeTrackedResources(intentData.key(), intentData.intent().resources());
+                intentsToApply.forEach(installable ->
+                                               trackerService.removeTrackedResources(intentData.intent().key(),
+                                                                                     installable.resources()));
+                break;
+        }
+    }
+
+    /**
+     * Determines whether there is any flow rule changed
+     * (i.e., different set of flow rules or different treatments)
+     * between FlowRuleIntents to be uninstalled and to be installed.
+     *
+     * @param uninstallIntent FlowRuleIntent to uninstall
+     * @param installIntent   FlowRuleIntent to install
+     * @return true if flow rules which to be uninstalled contains all flow
+     *         rules which to be installed; false otherwise
+     */
+    private boolean flowRuleIntentChanged(FlowRuleIntent uninstallIntent,
+                                          FlowRuleIntent installIntent) {
+        Collection<FlowRule> flowRulesToUninstall = uninstallIntent.flowRules();
+        Collection<FlowRule> flowRulesToInstall = installIntent.flowRules();
+
+        // Check if any flow rule changed
+        for (FlowRule flowRuleToInstall : flowRulesToInstall) {
+            if (flowRulesToUninstall.stream().noneMatch(flowRuleToInstall::exactMatch)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+}
\ No newline at end of file
