diff --git a/src/main/java/net/onrc/onos/api/flowmanager/PacketPathFlow.java b/src/main/java/net/onrc/onos/api/flowmanager/PacketPathFlow.java
index ce1fdb4..42cbd65 100644
--- a/src/main/java/net/onrc/onos/api/flowmanager/PacketPathFlow.java
+++ b/src/main/java/net/onrc/onos/api/flowmanager/PacketPathFlow.java
@@ -1,16 +1,24 @@
 package net.onrc.onos.api.flowmanager;
 
 import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
 
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.LinkedList;
 import java.util.List;
 
 import net.onrc.onos.api.flowmanager.FlowBatchOperation.Operator;
+import net.onrc.onos.core.matchaction.MatchAction;
 import net.onrc.onos.core.matchaction.MatchActionIdGenerator;
+import net.onrc.onos.core.matchaction.MatchActionOperationEntry;
 import net.onrc.onos.core.matchaction.MatchActionOperations;
 import net.onrc.onos.core.matchaction.MatchActionOperationsIdGenerator;
 import net.onrc.onos.core.matchaction.action.Action;
+import net.onrc.onos.core.matchaction.action.OutputAction;
 import net.onrc.onos.core.matchaction.match.PacketMatch;
 import net.onrc.onos.core.util.PortNumber;
+import net.onrc.onos.core.util.SwitchPort;
 
 /**
  * Flow object representing a packet path.
@@ -70,7 +78,105 @@
     public List<MatchActionOperations> compile(Operator op,
             MatchActionIdGenerator maIdGenerator,
             MatchActionOperationsIdGenerator maoIdGenerator) {
-        // TODO Auto-generated method stub
-        return null;
+        switch (op) {
+        case ADD:
+            return compileAddOperation(maIdGenerator, maoIdGenerator);
+        case REMOVE:
+            return compileRemoveOperation(maIdGenerator, maoIdGenerator);
+        default:
+            throw new UnsupportedOperationException("Unknown operation.");
+        }
+    }
+
+    /**
+     * Creates the next {@link MatchAction} object using iterators.
+     *
+     * @param portIterator the iterator for {@link SwitchPort} objects
+     * @param actionsIterator the iterator for the lists of {@link Action}
+     * @param maIdGenerator the ID generator of {@link MatchAction}
+     * @return {@link MatchAction} object based on the specified iterators
+     */
+    private MatchAction createNextMatchAction(Iterator<SwitchPort> portIterator,
+            Iterator<List<Action>> actionsIterator,
+            MatchActionIdGenerator maIdGenerator) {
+        if (portIterator == null || actionsIterator == null ||
+                !portIterator.hasNext() || !actionsIterator.hasNext()) {
+            return null;
+        }
+
+        // TODO: Update this after merging the new MatchAction API.
+        return new MatchAction(
+                maIdGenerator.getNewId(),
+                portIterator.next(),
+                getMatch(), actionsIterator.next());
+    }
+
+    /**
+     * Generates the list of {@link MatchActionOperations} objects with
+     * add-operation.
+     *
+     * @return the list of {@link MatchActionOperations} objects
+     */
+    private List<MatchActionOperations> compileAddOperation(
+            MatchActionIdGenerator maIdGenerator,
+            MatchActionOperationsIdGenerator maoIdGenerator) {
+        Path path = checkNotNull(getPath());
+        checkState(path.size() > 0, "Path object has no link.");
+
+        // Preparing each actions and ingress port for each switch
+        List<List<Action>> actionsList = new LinkedList<>();
+        List<SwitchPort> portList = new LinkedList<>();
+        for (FlowLink link : path) {
+            portList.add(link.getDstSwitchPort());
+            actionsList.add(Arrays.asList(
+                    (Action) new OutputAction(link.getSrcPortNumber())));
+        }
+
+        // The head switch's ingress port
+        portList.add(0, new SwitchPort(path.getSrcDpid(), getIngressPortNumber()));
+
+        // The tail switch's action
+        actionsList.add(getEgressActions());
+
+        Iterator<SwitchPort> portIterator = portList.iterator();
+        Iterator<List<Action>> actionsIterator = actionsList.iterator();
+
+        // Creates the second phase operation
+        // using the head switch's match action
+        MatchAction headMatchAction = createNextMatchAction(portIterator,
+                actionsIterator, maIdGenerator);
+        if (headMatchAction == null) {
+            return null;
+        }
+        MatchActionOperations secondOp = new MatchActionOperations(
+                maoIdGenerator.getNewId());
+        secondOp.addOperation(new MatchActionOperationEntry(
+                MatchActionOperations.Operator.ADD, headMatchAction));
+
+        // Creates the first phase operation
+        // using the remaining switches' match actions
+        MatchActionOperations firstOp = new MatchActionOperations(
+                maoIdGenerator.getNewId());
+        MatchAction ma;
+        while ((ma = createNextMatchAction(portIterator, actionsIterator, maIdGenerator)) != null) {
+            firstOp.addOperation(new MatchActionOperationEntry(
+                    MatchActionOperations.Operator.ADD, ma));
+        }
+
+        return Arrays.asList(firstOp, secondOp);
+    }
+
+    /**
+     * Generates the list of {@link MatchActionOperations} objects with
+     * remote-operation.
+     *
+     * @return the list of {@link MatchActionOperations} objects
+     */
+    private List<MatchActionOperations> compileRemoveOperation(
+            MatchActionIdGenerator maIdGenerator,
+            MatchActionOperationsIdGenerator maoIdGenerator) {
+        // TODO implement it
+        throw new UnsupportedOperationException(
+                "REMOVE operation is not implemented yet.");
     }
 }
diff --git a/src/test/java/net/onrc/onos/api/flowmanager/PacketPathFlowTest.java b/src/test/java/net/onrc/onos/api/flowmanager/PacketPathFlowTest.java
new file mode 100644
index 0000000..04e2649
--- /dev/null
+++ b/src/test/java/net/onrc/onos/api/flowmanager/PacketPathFlowTest.java
@@ -0,0 +1,234 @@
+package net.onrc.onos.api.flowmanager;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.Arrays;
+import java.util.List;
+
+import net.floodlightcontroller.util.MACAddress;
+import net.onrc.onos.core.matchaction.MatchAction;
+import net.onrc.onos.core.matchaction.MatchActionIdGeneratorWithIdBlockAllocator;
+import net.onrc.onos.core.matchaction.MatchActionOperationEntry;
+import net.onrc.onos.core.matchaction.MatchActionOperations;
+import net.onrc.onos.core.matchaction.MatchActionOperations.Operator;
+import net.onrc.onos.core.matchaction.MatchActionOperationsIdGeneratorWithIdBlockAllocator;
+import net.onrc.onos.core.matchaction.action.Action;
+import net.onrc.onos.core.matchaction.action.ModifyDstMacAction;
+import net.onrc.onos.core.matchaction.action.OutputAction;
+import net.onrc.onos.core.matchaction.match.PacketMatch;
+import net.onrc.onos.core.matchaction.match.PacketMatchBuilder;
+import net.onrc.onos.core.util.IdBlock;
+import net.onrc.onos.core.util.IdBlockAllocator;
+import net.onrc.onos.core.util.PortNumber;
+import net.onrc.onos.core.util.SwitchPort;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link PacketPathFlow} class.
+ */
+public class PacketPathFlowTest {
+    private Path pathWith4Switches;
+    private Path pathWith2Switches;
+    private PacketMatch match;
+    private List<Action> actions;
+    private IdBlockAllocator allocator;
+
+    @Before
+    public void setUp() throws Exception {
+        allocator = createMock(IdBlockAllocator.class);
+        expect(allocator.allocateUniqueIdBlock())
+                .andReturn(new IdBlock(0, 99))
+                .andReturn(new IdBlock(100, 199));
+        replay(allocator);
+
+        pathWith4Switches = new Path();
+        pathWith4Switches.add(new FlowLink(
+                new SwitchPort(1, (short) 10), new SwitchPort(2, (short) 11)));
+        pathWith4Switches.add(new FlowLink(
+                new SwitchPort(2, (short) 12), new SwitchPort(3, (short) 13)));
+        pathWith4Switches.add(new FlowLink(
+                new SwitchPort(3, (short) 14), new SwitchPort(4, (short) 15)));
+
+        pathWith2Switches = new Path();
+        pathWith2Switches.add(new FlowLink(
+                new SwitchPort(1, (short) 10), new SwitchPort(2, (short) 11)));
+
+        PacketMatchBuilder builder = new PacketMatchBuilder();
+        builder.setDstMac(MACAddress.valueOf(54321));
+        match = builder.build();
+
+        actions = Arrays.asList(
+                new ModifyDstMacAction(MACAddress.valueOf(12345)),
+                new OutputAction(PortNumber.uint32(101)));
+    }
+
+    @After
+    public void tearDown() throws Exception {
+    }
+
+    /**
+     * Checks the constructor initializes fields properly.
+     */
+    @Test
+    public void testConstructor() {
+        PacketPathFlow flow = new PacketPathFlow(
+                new FlowId(1L), match, PortNumber.uint32(100),
+                pathWith4Switches, actions, 0, 0);
+
+        assertNotNull(flow);
+        assertEquals(new FlowId(1L), flow.getId());
+        assertEquals(match, flow.getMatch());
+        assertEquals(PortNumber.uint32(100), flow.getIngressPortNumber());
+        assertEquals(pathWith4Switches, flow.getPath());
+        assertEquals(actions, flow.getEgressActions());
+        assertEquals(0, flow.getHardTimeout());
+        assertEquals(0, flow.getIdleTimeout());
+    }
+
+    /**
+     * Checks the compile method with add-operation. This test creates a flow
+     * object using the path with 2 switches, then checks if the compiled the
+     * list of MatchActionOperations objects are generated properly.
+     */
+    @Test
+    public void testCompileWithAddOperationFor2Switches() {
+        PacketPathFlow flow = new PacketPathFlow(
+                new FlowId(1L), match, PortNumber.uint32(100),
+                pathWith2Switches, actions, 0, 0);
+
+        List<MatchActionOperations> maOpsList =
+                flow.compile(FlowBatchOperation.Operator.ADD,
+                        new MatchActionIdGeneratorWithIdBlockAllocator(allocator),
+                        new MatchActionOperationsIdGeneratorWithIdBlockAllocator(
+                                allocator)
+                        );
+
+        assertEquals(2, maOpsList.size());
+
+        MatchActionOperations firstOp = maOpsList.get(0);
+        assertEquals(1, firstOp.size());
+        assertEquals(1, firstOp.getOperations().size());
+
+        MatchActionOperations secondOp = maOpsList.get(1);
+        assertEquals(1, secondOp.size());
+        assertEquals(1, secondOp.getOperations().size());
+
+        MatchActionOperationEntry entry1 = secondOp.getOperations().get(0);
+        MatchActionOperationEntry entry2 = firstOp.getOperations().get(0);
+
+        assertEquals(Operator.ADD, entry1.getOperator());
+        assertEquals(Operator.ADD, entry2.getOperator());
+
+        MatchAction ma1 = entry1.getTarget();
+        MatchAction ma2 = entry2.getTarget();
+
+        assertNotNull(ma1);
+        assertNotNull(ma2);
+
+        assertEquals(new SwitchPort(1, (short) 100), ma1.getSwitchPort());
+        assertEquals(new SwitchPort(2, (short) 11), ma2.getSwitchPort());
+
+        assertEquals(match, ma1.getMatch());
+        assertEquals(match, ma2.getMatch());
+
+        assertNotNull(ma1.getActions());
+        assertNotNull(ma2.getActions());
+
+        assertEquals(1, ma1.getActions().size());
+        assertEquals(2, ma2.getActions().size());
+
+        assertEquals(new OutputAction(PortNumber.uint32(10)),
+                ma1.getActions().get(0));
+        assertEquals(new ModifyDstMacAction(MACAddress.valueOf(12345)),
+                ma2.getActions().get(0));
+        assertEquals(new OutputAction(PortNumber.uint32(101)),
+                ma2.getActions().get(1));
+    }
+
+    /**
+     * Checks the compile method with add-operation. This test creates a flow
+     * object using the path with 4 switches, then checks if the compiled the
+     * list of MatchActionOperations objects are generated properly.
+     */
+    @Test
+    public void testCompileWithAddOperationFor4Switches() {
+        PacketPathFlow flow = new PacketPathFlow(
+                new FlowId(1L), match, PortNumber.uint32(100),
+                pathWith4Switches, actions, 0, 0);
+
+        List<MatchActionOperations> maOpsList =
+                flow.compile(FlowBatchOperation.Operator.ADD,
+                        new MatchActionIdGeneratorWithIdBlockAllocator(allocator),
+                        new MatchActionOperationsIdGeneratorWithIdBlockAllocator(
+                                allocator)
+                        );
+
+        assertEquals(2, maOpsList.size());
+
+        MatchActionOperations firstOp = maOpsList.get(0);
+        assertEquals(3, firstOp.size());
+        assertEquals(3, firstOp.getOperations().size());
+
+        MatchActionOperations secondOp = maOpsList.get(1);
+        assertEquals(1, secondOp.size());
+        assertEquals(1, secondOp.getOperations().size());
+
+        MatchActionOperationEntry entry1 = secondOp.getOperations().get(0);
+        MatchActionOperationEntry entry2 = firstOp.getOperations().get(0);
+        MatchActionOperationEntry entry3 = firstOp.getOperations().get(1);
+        MatchActionOperationEntry entry4 = firstOp.getOperations().get(2);
+
+        assertEquals(Operator.ADD, entry1.getOperator());
+        assertEquals(Operator.ADD, entry2.getOperator());
+        assertEquals(Operator.ADD, entry3.getOperator());
+        assertEquals(Operator.ADD, entry4.getOperator());
+
+        MatchAction ma1 = entry1.getTarget();
+        MatchAction ma2 = entry2.getTarget();
+        MatchAction ma3 = entry3.getTarget();
+        MatchAction ma4 = entry4.getTarget();
+
+        assertNotNull(ma1);
+        assertNotNull(ma2);
+        assertNotNull(ma3);
+        assertNotNull(ma4);
+
+        assertEquals(new SwitchPort(1, (short) 100), ma1.getSwitchPort());
+        assertEquals(new SwitchPort(2, (short) 11), ma2.getSwitchPort());
+        assertEquals(new SwitchPort(3, (short) 13), ma3.getSwitchPort());
+        assertEquals(new SwitchPort(4, (short) 15), ma4.getSwitchPort());
+
+        assertEquals(match, ma1.getMatch());
+        assertEquals(match, ma2.getMatch());
+        assertEquals(match, ma3.getMatch());
+        assertEquals(match, ma4.getMatch());
+
+        assertNotNull(ma1.getActions());
+        assertNotNull(ma2.getActions());
+        assertNotNull(ma3.getActions());
+        assertNotNull(ma4.getActions());
+
+        assertEquals(1, ma1.getActions().size());
+        assertEquals(1, ma2.getActions().size());
+        assertEquals(1, ma3.getActions().size());
+        assertEquals(2, ma4.getActions().size());
+
+        assertEquals(new OutputAction(PortNumber.uint32(10)),
+                ma1.getActions().get(0));
+        assertEquals(new OutputAction(PortNumber.uint32(12)),
+                ma2.getActions().get(0));
+        assertEquals(new OutputAction(PortNumber.uint32(14)),
+                ma3.getActions().get(0));
+        assertEquals(new ModifyDstMacAction(MACAddress.valueOf(12345)),
+                ma4.getActions().get(0));
+        assertEquals(new OutputAction(PortNumber.uint32(101)),
+                ma4.getActions().get(1));
+    }
+}
