diff --git a/apps/intent-perf/src/assembly/app.xml b/apps/intent-perf/src/assembly/app.xml
new file mode 100644
index 0000000..dcc6ec8
--- /dev/null
+++ b/apps/intent-perf/src/assembly/app.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+<app name="org.onosproject.intentperf" origin="ON.Lab" version="1.1.0"
+     features="onos-app-intent-perf">
+    <description>Intent performance application</description>
+</app>
\ No newline at end of file
diff --git a/apps/intent-perf/src/assembly/bin.xml b/apps/intent-perf/src/assembly/bin.xml
new file mode 100644
index 0000000..b92fa72
--- /dev/null
+++ b/apps/intent-perf/src/assembly/bin.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+<assembly
+        xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
+    <formats>
+        <format>zip</format>
+    </formats>
+    <id>onos</id>
+    <includeBaseDirectory>false</includeBaseDirectory>
+    <files>
+        <file>
+            <source>src/assembly/app.xml</source>
+            <destName>app.xml</destName>
+        </file>
+        <file>
+            <source>target/${project.artifactId}-${project.version}.jar</source>
+            <destName>m2/org/onosproject/${project.artifactId}/${project.version}/${project.artifactId}-${project.version}.jar</destName>
+        </file>
+    </files>
+</assembly>
\ No newline at end of file
diff --git a/apps/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfInstaller.java b/apps/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfInstaller.java
new file mode 100644
index 0000000..19cc06d
--- /dev/null
+++ b/apps/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfInstaller.java
@@ -0,0 +1,259 @@
+/*
+ * 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.intentperf;
+
+import com.google.common.collect.Lists;
+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.onlab.util.Counter;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Device;
+import org.onosproject.net.PortNumber;
+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.intent.Intent;
+import org.onosproject.net.intent.IntentEvent;
+import org.onosproject.net.intent.IntentListener;
+import org.onosproject.net.intent.IntentService;
+import org.onosproject.net.intent.Key;
+import org.onosproject.net.intent.PointToPointIntent;
+import org.slf4j.Logger;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import static org.onlab.util.Tools.delay;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Application to set up demos.
+ */
+@Component(immediate = true)
+public class IntentPerfInstaller {
+
+    private final Logger log = getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected IntentService intentService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ClusterService clusterService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    private ExecutorService worker;
+    private ApplicationId appId;
+    private Listener listener;
+    private Set<Intent> intents;
+    private Set<Intent> submitted;
+    private Set<Intent> withdrawn;
+    private boolean stopped;
+
+    private static final long REPORT_PERIOD = 5000L; //ms
+    private Timer reportTimer;
+
+    //FIXME make this configurable
+    private static final int NUM_KEYS = 10000;
+
+    @Activate
+    public void activate() {
+        String nodeId = clusterService.getLocalNode().ip().toString();
+        appId = coreService.registerApplication("org.onosproject.intentperf."
+                                                        + nodeId);
+        intents = Sets.newHashSet();
+        submitted = Sets.newHashSet();
+        withdrawn = Sets.newHashSet();
+
+        worker = Executors.newFixedThreadPool(1, groupedThreads("onos/intent-perf", "worker"));
+        log.info("Started with Application ID {}", appId.id());
+        start(); //FIXME
+    }
+
+    @Deactivate
+    public void deactivate() {
+        stop();
+        log.info("Stopped");
+    }
+
+    public void start() {
+        // perhaps we want to prime before listening...
+        // we will need to discard the first few results for priming and warmup
+        listener = new Listener();
+        intentService.addListener(listener);
+        reportTimer = new Timer("intent-perf-reporter");
+        reportTimer.scheduleAtFixedRate(new TimerTask() {
+            @Override
+            public void run() {
+                listener.report();
+            }
+        }, REPORT_PERIOD, REPORT_PERIOD);
+
+        stopped = false;
+        worker.submit(() -> {
+            delay(2000);
+            createIntents(NUM_KEYS, 2); //FIXME
+            prime();
+            while (!stopped) {
+                cycle();
+                // TODO delay if required
+            }
+        });
+
+    }
+
+    public void stop() {
+        if (listener != null) {
+            reportTimer.cancel();
+            intentService.removeListener(listener);
+            listener = null;
+            reportTimer = null;
+        }
+        stopped = true;
+        try {
+            worker.awaitTermination(5, TimeUnit.SECONDS);
+        } catch (InterruptedException e) {
+            log.warn("Failed to stop worker.");
+        }
+    }
+
+
+    private void cycle() {
+        subset(submitted).forEach(this::withdraw);
+        subset(withdrawn).forEach(this::submit);
+    }
+
+    private Iterable<Intent> subset(Set<Intent> intents) {
+        List<Intent> subset = Lists.newArrayList(intents);
+        Collections.shuffle(subset);
+        return subset.subList(0, subset.size() / 2);
+    }
+
+    private void submit(Intent intent) {
+        intentService.submit(intent);
+        submitted.add(intent);
+        withdrawn.remove(intent); //TODO could check result here...
+    }
+
+    private void withdraw(Intent intent) {
+        intentService.withdraw(intent);
+        withdrawn.add(intent);
+        submitted.remove(intent); //TODO could check result here...
+    }
+
+    private void createIntents(int numberOfKeys, int pathLength) {
+
+        Iterator<Device> deviceItr = deviceService.getAvailableDevices().iterator();
+
+        if (!deviceItr.hasNext()) {
+            throw new IllegalStateException("There are no devices");
+        }
+
+        Device ingressDevice = deviceItr.next();
+
+        for (int i = 0; i < numberOfKeys; i++) {
+            Key key = Key.of(i, appId);
+            TrafficSelector selector = DefaultTrafficSelector.builder().build();
+
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
+            //FIXME
+            ConnectPoint ingress = new ConnectPoint(ingressDevice.id(), PortNumber.portNumber(1));
+            ConnectPoint egress = new ConnectPoint(ingressDevice.id(), PortNumber.portNumber(2));
+
+            Intent intent = new PointToPointIntent(appId, key,
+                                                   selector, treatment,
+                                                   ingress, egress,
+                                                   Collections.emptyList());
+            intents.add(intent);
+        }
+    }
+
+    private void prime() {
+        int i = 0;
+        withdrawn.addAll(intents);
+        for (Intent intent : intents) {
+            submit(intent);
+            // only submit half of the intents to start
+            if (i++ >= intents.size() / 2) {
+                break;
+            }
+        }
+    }
+
+    class Listener implements IntentListener {
+
+
+        private Map<IntentEvent.Type, Counter> counters;
+
+        public Listener() {
+            counters = initCounters();
+
+        }
+
+        private Map<IntentEvent.Type, Counter> initCounters() {
+            Map<IntentEvent.Type, Counter> map = Maps.newHashMap();
+            for (IntentEvent.Type type : IntentEvent.Type.values()) {
+                map.put(type, new Counter());
+            }
+            return map;
+        }
+
+        @Override
+        public void event(IntentEvent event) {
+            if (event.subject().appId().equals(appId)) {
+                counters.get(event.type()).add(1);
+            }
+        }
+
+        public void report() {
+            StringBuilder stringBuilder = new StringBuilder();
+            for (IntentEvent.Type type : IntentEvent.Type.values()) {
+                stringBuilder.append(printCounter(type)).append("; ");
+            }
+            log.info("Intent Throughput:\n{}", stringBuilder);
+        }
+
+        private String printCounter(IntentEvent.Type event) {
+            Counter counter = counters.get(event);
+            String result = String.format("%s=%.2f", event, counter.throughput());
+            counter.reset();
+            return result;
+        }
+    }
+}
