diff --git a/core/api/src/main/java/org/onosproject/net/packet/packetfilter/DefaultPacketInFilter.java b/core/api/src/main/java/org/onosproject/net/packet/packetfilter/DefaultPacketInFilter.java
new file mode 100644
index 0000000..d628f80
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/packet/packetfilter/DefaultPacketInFilter.java
@@ -0,0 +1,324 @@
+/*
+ * Copyright 2019-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.packet.packetfilter;
+
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketInClassifier;
+import org.onosproject.net.packet.PacketInFilter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Objects;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static org.onlab.util.Tools.groupedThreads;
+
+/**
+ * Default implementation of a packet-in filter.
+ */
+public class DefaultPacketInFilter implements PacketInFilter {
+
+    /**
+     * Tracks the count of specific packet types (eg ARP, ND, DHCP etc)
+     * to be limited in the packet queue. This count always reflects the
+     * number of packets in the queue at any point in time
+     */
+    private AtomicInteger currentCounter = new AtomicInteger(0);
+
+    /**
+     * Tracks the number of continuous windows where the drop packet happens.
+     */
+    private AtomicInteger windowBlockCounter = new AtomicInteger(0);
+
+    /**
+     * Tracks the counter of the packet which are dropped.
+     */
+    private AtomicInteger overFlowCounter = new AtomicInteger(0);
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    /**
+     * Max Allowed packet rate beyond which the packet will be dropped
+     * within given window size.
+     */
+    private int pps = 100;
+
+    /**
+     * Window size which will be used for number of packets acceptable
+     * based on the accepted pps.
+     */
+    private int winSize = 500;
+
+    /**
+     * Guard time in seconds which will be enabled if there are continuous
+     * windows crossing winThres where the packet rate crosses the acceptable
+     * packet count calculated based on accepted pps.
+     * Guard time should be always greater then the the window size.
+     */
+    private int guardTime = 10;
+
+    /**
+     * Threshold of continuous windows where the packet drop happens post which
+     * the guardTime will be triggered and no future packet processing happens
+     * till the expiry of this guard time.
+     */
+    private int winThres = 10;
+
+
+    private int maxCounter;
+
+    private ScheduledExecutorService timerExecutor;
+
+    private ScheduledExecutorService windowUnblockExecutor;
+
+    private boolean windowBlocked;
+
+    private boolean packetProcessingBlocked;
+
+
+    /**
+     * Name of the counter.
+     */
+    private String counterName;
+
+    /**
+     * PacketInclassifier associated with this filter object.
+     */
+    private final PacketInClassifier classifier;
+
+
+
+    /**
+     * Only one filter object per packet type to be associated.
+     * Multiple filter types will result in undefined behavior.
+     * @param pps Rate at which the packet is accepted in packets per second
+     * @param winSize Size of window in milli seconds within which
+     *                the packet rate will be analyzed
+     * @param guardTime Time duration in seconds for which the packet processing
+     *                  will be on hold if there is a continuous window where
+     *                  cross of the rate happens and that window count crosses
+     *                  winThres
+     * @param winThres Continuous window threshold after which gaurdTime will be
+     *                 activated
+     * @param counterName Name of the counter
+     * @param classifier Packet classification
+     */
+    public DefaultPacketInFilter(int pps, int winSize, int guardTime, int winThres,
+                                 String counterName, PacketInClassifier classifier) {
+        this.pps = pps;
+        this.winSize = winSize;
+        this.guardTime = guardTime;
+        this.winThres = winThres;
+        this.counterName = counterName;
+        this.classifier = classifier;
+        this.maxCounter = (pps * winSize) / 1000;
+        timerExecutor = Executors.newScheduledThreadPool(1,
+                                                         groupedThreads("packet/packetfilter",
+                                                                        "packet-filter-timer-%d", log));
+
+        windowUnblockExecutor = Executors.newScheduledThreadPool(1,
+                                                                 groupedThreads("packet/packetfilter",
+                                                                                "packet-filter-unblocker-%d", log));
+        timerExecutor.scheduleAtFixedRate(new ClearWindowBlock(),
+                                          0,
+                                          winSize,
+                                          TimeUnit.MILLISECONDS);
+
+
+        windowBlocked = false;
+        packetProcessingBlocked = false;
+
+    }
+
+
+
+    @Override
+    public FilterAction preProcess(PacketContext packet) {
+
+
+        maxCounter = (pps * winSize) / 1000;
+
+        // If pps is set then min value for maxCounter is 1
+        if (maxCounter == 0 && pps != 0) {
+            log.trace("{}: maxCounter set to 1 as was coming as 0", counterName);
+            maxCounter = 1;
+        }
+
+
+
+        if (!classifier.match(packet)) {
+            return FilterAction.FILTER_INVALID;
+        }
+
+        if (pps == 0 && maxCounter == 0) {
+            log.trace("{}: Filter is disabled", counterName);
+            return FilterAction.FILTER_DISABLED;
+        }
+        log.trace("{}: Preprocess called", counterName);
+
+        // Packet block checking should be done before windowBlocked checking
+        // otherwise there will be windows with packets while packet processing is suspended
+        // and that may break the existing check logic
+        if (packetProcessingBlocked) {
+            log.trace("{}: Packet processing is blocked for sometime", counterName);
+            return FilterAction.PACKET_BLOCKED;
+        }
+
+        if (windowBlocked) {
+            log.trace("{}: Packet processing is blocked for the window number: {}",
+                      counterName, windowBlockCounter.get());
+            return FilterAction.WINDOW_BLOCKED;
+        }
+
+        if (currentCounter.getAndIncrement() < maxCounter) {
+            log.trace("{}: Packet is picked for processing with currentCounter: {} and maxCounter: {}",
+                      counterName, currentCounter.get(), maxCounter);
+            return FilterAction.PACKET_ALLOW;
+        }
+        //Need to decrement the currentCounter and increment overFlowCounter
+        //Need to block the window and increment the window block counter
+        windowBlocked = true;
+        //TODO: Review this and the complete state machine
+        // If windowBlock crosses threshold then block packet processing for guard time
+        if (windowBlockCounter.incrementAndGet() > winThres) {
+            log.trace("{}: Packet processing blocked as current window crossed threshold " +
+                       "currentWindowNumber: {} maxWindowNumber: {}",
+                       counterName, windowBlockCounter.get(), winThres);
+            packetProcessingBlocked = true;
+            windowUnblockExecutor.schedule(new ClearPacketProcessingBlock(),
+                                                         guardTime,
+                                                         TimeUnit.SECONDS);
+        } else {
+            log.trace("{}: WindowBlockCounter: {} winThres: {}", counterName, windowBlockCounter.get(),
+            winThres);
+        }
+        //MT: Temp change in logic to branch the code - Rolled back
+        currentCounter.decrementAndGet();
+        if (overFlowCounter.incrementAndGet() < 0) {
+            overFlowCounter.set(0);
+        }
+        log.trace("{}: Overflow counter is: {}", counterName, overFlowCounter.get());
+        return FilterAction.PACKET_DENY;
+
+    }
+
+    @Override
+    public String name() {
+        return counterName;
+    }
+
+    @Override
+    public int pendingPackets() {
+        return currentCounter.get();
+    }
+
+    @Override
+    public int droppedPackets() {
+       return overFlowCounter.get();
+    }
+
+
+
+    @Override
+    public void setPps(int pps) {
+        this.pps = pps;
+    }
+
+    @Override
+    public void setWinSize(int winSize) {
+        this.winSize = winSize;
+    }
+
+    @Override
+    public void setGuardTime(int guardTime) {
+        this.guardTime = guardTime;
+    }
+
+    @Override
+    public void setWinThres(int winThres) {
+        this.winThres = winThres;
+    }
+
+    @Override
+    public void stop() {
+        timerExecutor.shutdown();
+        windowUnblockExecutor.shutdown();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        DefaultPacketInFilter that = (DefaultPacketInFilter) o;
+        return pps == that.pps &&
+                winSize == that.winSize &&
+                guardTime == that.guardTime &&
+                winThres == that.winThres &&
+                counterName.equals(that.counterName) &&
+                classifier.equals(that.classifier);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(pps, winSize, guardTime, winThres, counterName, classifier);
+    }
+
+
+    private final class ClearWindowBlock implements Runnable {
+        @Override
+        public void run() {
+            // If window is not already blocked and there is at least one packet processed
+            // in that window then reset the window block counter:
+            if (!windowBlocked) {
+                log.trace("{}: WindowBlockCounter is reset as there was no blocking in current " +
+                          "window with current windowBlockCounter: {}", counterName, windowBlockCounter.get());
+                windowBlockCounter.set(0);
+            }
+            if (currentCounter.get() == 0) {
+                //No packet processed in current window so do not change anything in the current state
+                log.trace("{}: No packets in the current window so not doing anything in ClearWindowBlock",
+                          counterName);
+                return;
+            }
+
+            //Reset the counter and unblock the window
+            log.trace("{}: Current counter and windowBlocked is reset in ClearWindowBlock", counterName);
+            currentCounter.set(0);
+            windowBlocked = false;
+        }
+    }
+
+    private final class ClearPacketProcessingBlock implements Runnable {
+        @Override
+        public void run() {
+            //Reset the counter and unblock the window and packet processing
+            //CurrentCounter and windowBlocked counter setting is not required here
+            //Still setting to be on safer side
+            log.trace("{}: All blocks cleared in ClearPacketProcessingBlock", counterName);
+            currentCounter.set(0);
+            windowBlocked = false;
+            packetProcessingBlocked = false;
+            windowBlockCounter.set(0);
+        }
+    }
+}
