diff --git a/cmd/podman/commands.go b/cmd/podman/commands.go
index c261e54e27..483ada3325 100644
--- a/cmd/podman/commands.go
+++ b/cmd/podman/commands.go
@@ -85,14 +85,6 @@ func getContainerSubCommands() []*cobra.Command {
 	}
 }
 
-// Commands that the local client implements
-func getPodSubCommands() []*cobra.Command {
-	return []*cobra.Command{
-		_podStatsCommand,
-		_podTopCommand,
-	}
-}
-
 func getGenerateSubCommands() []*cobra.Command {
 	return []*cobra.Command{
 		_containerKubeCommand,
diff --git a/cmd/podman/commands_remoteclient.go b/cmd/podman/commands_remoteclient.go
index 081043b257..a278761c18 100644
--- a/cmd/podman/commands_remoteclient.go
+++ b/cmd/podman/commands_remoteclient.go
@@ -28,11 +28,6 @@ func getContainerSubCommands() []*cobra.Command {
 	return []*cobra.Command{}
 }
 
-// commands that only the remoteclient implements
-func getPodSubCommands() []*cobra.Command {
-	return []*cobra.Command{}
-}
-
 // commands that only the remoteclient implements
 func getGenerateSubCommands() []*cobra.Command {
 	return []*cobra.Command{}
diff --git a/cmd/podman/pod.go b/cmd/podman/pod.go
index c1350bd4dd..7067f24292 100644
--- a/cmd/podman/pod.go
+++ b/cmd/podman/pod.go
@@ -29,12 +29,13 @@ var podSubCommands = []*cobra.Command{
 	_podRestartCommand,
 	_podRmCommand,
 	_podStartCommand,
+	_podStatsCommand,
 	_podStopCommand,
+	_podTopCommand,
 	_podUnpauseCommand,
 }
 
 func init() {
 	podCommand.AddCommand(podSubCommands...)
-	podCommand.AddCommand(getPodSubCommands()...)
 	podCommand.SetUsageTemplate(UsageTemplate())
 }
diff --git a/cmd/podman/pod_stats.go b/cmd/podman/pod_stats.go
index f5edd21f88..2761ce9ccb 100644
--- a/cmd/podman/pod_stats.go
+++ b/cmd/podman/pod_stats.go
@@ -13,8 +13,8 @@ import (
 	tm "github.com/buger/goterm"
 	"github.com/containers/libpod/cmd/podman/cliconfig"
 	"github.com/containers/libpod/cmd/podman/formats"
-	"github.com/containers/libpod/cmd/podman/libpodruntime"
 	"github.com/containers/libpod/libpod"
+	"github.com/containers/libpod/pkg/adapter"
 	"github.com/pkg/errors"
 	"github.com/spf13/cobra"
 	"github.com/ulule/deepcopier"
@@ -51,10 +51,6 @@ func init() {
 }
 
 func podStatsCmd(c *cliconfig.PodStatsValues) error {
-	var (
-		podFunc func() ([]*libpod.Pod, error)
-	)
-
 	format := c.Format
 	all := c.All
 	latest := c.Latest
@@ -76,7 +72,7 @@ func podStatsCmd(c *cliconfig.PodStatsValues) error {
 		all = true
 	}
 
-	runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
+	runtime, err := adapter.GetRuntime(&c.PodmanCommand)
 	if err != nil {
 		return errors.Wrapf(err, "could not get runtime")
 	}
@@ -87,29 +83,12 @@ func podStatsCmd(c *cliconfig.PodStatsValues) error {
 		times = 1
 	}
 
-	if len(c.InputArgs) > 0 {
-		podFunc = func() ([]*libpod.Pod, error) { return getPodsByList(c.InputArgs, runtime) }
-	} else if latest {
-		podFunc = func() ([]*libpod.Pod, error) {
-			latestPod, err := runtime.GetLatestPod()
-			if err != nil {
-				return nil, err
-			}
-			return []*libpod.Pod{latestPod}, err
-		}
-	} else if all {
-		podFunc = runtime.GetAllPods
-	} else {
-		podFunc = runtime.GetRunningPods
-	}
-
-	pods, err := podFunc()
+	pods, err := runtime.GetStatPods(c)
 	if err != nil {
 		return errors.Wrapf(err, "unable to get a list of pods")
 	}
-
 	// First we need to get an initial pass of pod/ctr stats (these are not printed)
-	var podStats []*libpod.PodContainerStats
+	var podStats []*adapter.PodContainerStats
 	for _, p := range pods {
 		cons, err := p.AllContainersByID()
 		if err != nil {
@@ -120,7 +99,7 @@ func podStatsCmd(c *cliconfig.PodStatsValues) error {
 		for _, c := range cons {
 			emptyStats[c] = &libpod.ContainerStats{}
 		}
-		ps := libpod.PodContainerStats{
+		ps := adapter.PodContainerStats{
 			Pod:            p,
 			ContainerStats: emptyStats,
 		}
@@ -128,10 +107,10 @@ func podStatsCmd(c *cliconfig.PodStatsValues) error {
 	}
 
 	// Create empty container stat results for our first pass
-	var previousPodStats []*libpod.PodContainerStats
+	var previousPodStats []*adapter.PodContainerStats
 	for _, p := range pods {
 		cs := make(map[string]*libpod.ContainerStats)
-		pcs := libpod.PodContainerStats{
+		pcs := adapter.PodContainerStats{
 			Pod:            p,
 			ContainerStats: cs,
 		}
@@ -164,7 +143,7 @@ func podStatsCmd(c *cliconfig.PodStatsValues) error {
 	}
 
 	for i := 0; i < times; i += step {
-		var newStats []*libpod.PodContainerStats
+		var newStats []*adapter.PodContainerStats
 		for _, p := range pods {
 			prevStat := getPreviousPodContainerStats(p.ID(), previousPodStats)
 			newPodStats, err := p.GetPodStats(prevStat)
@@ -174,7 +153,7 @@ func podStatsCmd(c *cliconfig.PodStatsValues) error {
 			if err != nil {
 				return err
 			}
-			newPod := libpod.PodContainerStats{
+			newPod := adapter.PodContainerStats{
 				Pod:            p,
 				ContainerStats: newPodStats,
 			}
@@ -202,7 +181,7 @@ func podStatsCmd(c *cliconfig.PodStatsValues) error {
 		time.Sleep(time.Second)
 		previousPodStats := new([]*libpod.PodContainerStats)
 		deepcopier.Copy(newStats).To(previousPodStats)
-		pods, err = podFunc()
+		pods, err = runtime.GetStatPods(c)
 		if err != nil {
 			return err
 		}
@@ -211,7 +190,7 @@ func podStatsCmd(c *cliconfig.PodStatsValues) error {
 	return nil
 }
 
-func podContainerStatsToPodStatOut(stats []*libpod.PodContainerStats) []*podStatOut {
+func podContainerStatsToPodStatOut(stats []*adapter.PodContainerStats) []*podStatOut {
 	var out []*podStatOut
 	for _, p := range stats {
 		for _, c := range p.ContainerStats {
@@ -295,7 +274,7 @@ func outputToStdOut(stats []*podStatOut) {
 	w.Flush()
 }
 
-func getPreviousPodContainerStats(podID string, prev []*libpod.PodContainerStats) map[string]*libpod.ContainerStats {
+func getPreviousPodContainerStats(podID string, prev []*adapter.PodContainerStats) map[string]*libpod.ContainerStats {
 	for _, p := range prev {
 		if podID == p.Pod.ID() {
 			return p.ContainerStats
@@ -304,7 +283,7 @@ func getPreviousPodContainerStats(podID string, prev []*libpod.PodContainerStats
 	return map[string]*libpod.ContainerStats{}
 }
 
-func outputJson(stats []*libpod.PodContainerStats) error {
+func outputJson(stats []*adapter.PodContainerStats) error {
 	b, err := json.MarshalIndent(&stats, "", "     ")
 	if err != nil {
 		return err
diff --git a/cmd/podman/pod_top.go b/cmd/podman/pod_top.go
index 6a26e3dffd..c5383d3766 100644
--- a/cmd/podman/pod_top.go
+++ b/cmd/podman/pod_top.go
@@ -2,13 +2,12 @@ package main
 
 import (
 	"fmt"
+	"github.com/containers/libpod/pkg/adapter"
 	"os"
 	"strings"
 	"text/tabwriter"
 
 	"github.com/containers/libpod/cmd/podman/cliconfig"
-	"github.com/containers/libpod/cmd/podman/libpodruntime"
-	"github.com/containers/libpod/cmd/podman/shared"
 	"github.com/containers/libpod/libpod"
 	"github.com/pkg/errors"
 	"github.com/spf13/cobra"
@@ -50,8 +49,9 @@ func init() {
 }
 
 func podTopCmd(c *cliconfig.PodTopValues) error {
-	var pod *libpod.Pod
-	var err error
+	var (
+		descriptors []string
+	)
 	args := c.InputArgs
 
 	if c.ListDescriptors {
@@ -67,39 +67,22 @@ func podTopCmd(c *cliconfig.PodTopValues) error {
 		return errors.Errorf("you must provide the name or id of a running pod")
 	}
 
-	runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
+	runtime, err := adapter.GetRuntime(&c.PodmanCommand)
 	if err != nil {
 		return errors.Wrapf(err, "error creating libpod runtime")
 	}
 	defer runtime.Shutdown(false)
 
-	var descriptors []string
 	if c.Latest {
 		descriptors = args
-		pod, err = runtime.GetLatestPod()
 	} else {
 		descriptors = args[1:]
-		pod, err = runtime.LookupPod(args[0])
 	}
-
-	if err != nil {
-		return errors.Wrapf(err, "unable to lookup requested container")
-	}
-
-	podStatus, err := shared.GetPodStatus(pod)
-	if err != nil {
-		return err
-	}
-	if podStatus != "Running" {
-		return errors.Errorf("pod top can only be used on pods with at least one running container")
-	}
-
-	psOutput, err := pod.GetPodPidInformation(descriptors)
-	if err != nil {
-		return err
-	}
-
 	w := tabwriter.NewWriter(os.Stdout, 5, 1, 3, ' ', 0)
+	psOutput, err := runtime.PodTop(c, descriptors)
+	if err != nil {
+		return err
+	}
 	for _, proc := range psOutput {
 		fmt.Fprintln(w, proc)
 	}
diff --git a/cmd/podman/varlink/io.podman.varlink b/cmd/podman/varlink/io.podman.varlink
index 73e6c15f93..a50b7dd13e 100644
--- a/cmd/podman/varlink/io.podman.varlink
+++ b/cmd/podman/varlink/io.podman.varlink
@@ -549,6 +549,10 @@ method ExportContainer(name: string, path: string) -> (tarfile: string)
 # ~~~
 method GetContainerStats(name: string) -> (container: ContainerStats)
 
+# GetContainerStatsWithHistory takes a previous set of container statistics and uses libpod functions
+# to calculate the containers statistics based on current and previous measurements.
+method GetContainerStatsWithHistory(previousStats: ContainerStats) -> (container: ContainerStats)
+
 # This method has not be implemented yet.
 # method ResizeContainerTty() -> (notimplemented: NotImplemented)
 
@@ -952,8 +956,7 @@ method RemovePod(name: string, force: bool) -> (pod: string)
 # This method has not be implemented yet.
 # method WaitPod() -> (notimplemented: NotImplemented)
 
-# This method has not been implemented yet.
-# method TopPod() -> (notimplemented: NotImplemented)
+method TopPod(pod: string, latest: bool, descriptors: []string) -> (stats: []string)
 
 # GetPodStats takes the name or ID of a pod and returns a pod name and slice of ContainerStats structure which
 # contains attributes like memory and cpu usage.  If the pod cannot be found, a [PodNotFound](#PodNotFound)
diff --git a/pkg/adapter/pods.go b/pkg/adapter/pods.go
index 706a8fe961..669971789e 100644
--- a/pkg/adapter/pods.go
+++ b/pkg/adapter/pods.go
@@ -4,6 +4,7 @@ package adapter
 
 import (
 	"context"
+	"github.com/pkg/errors"
 	"strings"
 
 	"github.com/containers/libpod/cmd/podman/cliconfig"
@@ -17,6 +18,13 @@ type Pod struct {
 	*libpod.Pod
 }
 
+// PodContainerStats is struct containing an adapter Pod and a libpod
+// ContainerStats and is used primarily for outputing pod stats.
+type PodContainerStats struct {
+	Pod            *Pod
+	ContainerStats map[string]*libpod.ContainerStats
+}
+
 // RemovePods ...
 func (r *LocalRuntime) RemovePods(ctx context.Context, cli *cliconfig.PodRmValues) ([]string, []error) {
 	var (
@@ -321,3 +329,55 @@ func (r *LocalRuntime) RestartPods(ctx context.Context, c *cliconfig.PodRestartV
 	return restartIDs, containerErrors, restartErrors
 
 }
+
+// PodTop is a wrapper function to call GetPodPidInformation in libpod and return its results
+// for output
+func (r *LocalRuntime) PodTop(c *cliconfig.PodTopValues, descriptors []string) ([]string, error) {
+	var (
+		pod *Pod
+		err error
+	)
+
+	if c.Latest {
+		pod, err = r.GetLatestPod()
+	} else {
+		pod, err = r.LookupPod(c.InputArgs[0])
+	}
+	if err != nil {
+		return nil, errors.Wrapf(err, "unable to lookup requested container")
+	}
+	podStatus, err := pod.GetPodStatus()
+	if err != nil {
+		return nil, errors.Wrapf(err, "unable to get status for pod %s", pod.ID())
+	}
+	if podStatus != "Running" {
+		return nil, errors.Errorf("pod top can only be used on pods with at least one running container")
+	}
+	return pod.GetPodPidInformation(descriptors)
+}
+
+// GetStatPods returns pods for use in pod stats
+func (r *LocalRuntime) GetStatPods(c *cliconfig.PodStatsValues) ([]*Pod, error) {
+	var (
+		adapterPods []*Pod
+		pods        []*libpod.Pod
+		err         error
+	)
+
+	if len(c.InputArgs) > 0 || c.Latest || c.All {
+		pods, err = shortcuts.GetPodsByContext(c.All, c.Latest, c.InputArgs, r.Runtime)
+	} else {
+		pods, err = r.Runtime.GetRunningPods()
+	}
+	if err != nil {
+		return nil, err
+	}
+	// convert libpod pods to adapter pods
+	for _, p := range pods {
+		adapterPod := Pod{
+			p,
+		}
+		adapterPods = append(adapterPods, &adapterPod)
+	}
+	return adapterPods, nil
+}
diff --git a/pkg/adapter/pods_remote.go b/pkg/adapter/pods_remote.go
index 220f7163fa..ef8de90a68 100644
--- a/pkg/adapter/pods_remote.go
+++ b/pkg/adapter/pods_remote.go
@@ -12,6 +12,7 @@ import (
 	"github.com/containers/libpod/cmd/podman/shared"
 	"github.com/containers/libpod/cmd/podman/varlink"
 	"github.com/containers/libpod/libpod"
+	"github.com/containers/libpod/pkg/varlinkapi"
 	"github.com/pkg/errors"
 	"github.com/ulule/deepcopier"
 )
@@ -21,6 +22,13 @@ type Pod struct {
 	remotepod
 }
 
+// PodContainerStats is struct containing an adapter Pod and a libpod
+// ContainerStats and is used primarily for outputing pod stats.
+type PodContainerStats struct {
+	Pod            *Pod
+	ContainerStats map[string]*libpod.ContainerStats
+}
+
 type remotepod struct {
 	config     *libpod.PodConfig
 	state      *libpod.PodInspectState
@@ -399,3 +407,103 @@ func (r *LocalRuntime) RestartPods(ctx context.Context, c *cliconfig.PodRestartV
 	}
 	return restartIDs, nil, restartErrors
 }
+
+// PodTop gets top statistics for a pod
+func (r *LocalRuntime) PodTop(c *cliconfig.PodTopValues, descriptors []string) ([]string, error) {
+	var (
+		latest  bool
+		podName string
+	)
+	if c.Latest {
+		latest = true
+	} else {
+		podName = c.InputArgs[0]
+	}
+	return iopodman.TopPod().Call(r.Conn, podName, latest, descriptors)
+}
+
+// GetStatPods returns pods for use in pod stats
+func (r *LocalRuntime) GetStatPods(c *cliconfig.PodStatsValues) ([]*Pod, error) {
+	var (
+		pods    []*Pod
+		err     error
+		podIDs  []string
+		running bool
+	)
+
+	if len(c.InputArgs) > 0 || c.Latest || c.All {
+		podIDs, err = iopodman.GetPodsByContext().Call(r.Conn, c.All, c.Latest, c.InputArgs)
+	} else {
+		podIDs, err = iopodman.GetPodsByContext().Call(r.Conn, true, false, []string{})
+		running = true
+	}
+	if err != nil {
+		return nil, err
+	}
+	for _, p := range podIDs {
+		pod, err := r.Inspect(p)
+		if err != nil {
+			return nil, err
+		}
+		if running {
+			status, err := pod.GetPodStatus()
+			if err != nil {
+				// if we cannot get the status of the pod, skip and move on
+				continue
+			}
+			if strings.ToUpper(status) != "RUNNING" {
+				// if the pod is not running, skip and move on as well
+				continue
+			}
+		}
+		pods = append(pods, pod)
+	}
+	return pods, nil
+}
+
+// GetPodStats returns the stats for each of its containers
+func (p *Pod) GetPodStats(previousContainerStats map[string]*libpod.ContainerStats) (map[string]*libpod.ContainerStats, error) {
+	var (
+		ok       bool
+		prevStat *libpod.ContainerStats
+	)
+	newContainerStats := make(map[string]*libpod.ContainerStats)
+	containers, err := p.AllContainers()
+	if err != nil {
+		return nil, err
+	}
+	for _, c := range containers {
+		if prevStat, ok = previousContainerStats[c.ID()]; !ok {
+			prevStat = &libpod.ContainerStats{ContainerID: c.ID()}
+		}
+		cStats := iopodman.ContainerStats{
+			Id:           prevStat.ContainerID,
+			Name:         prevStat.Name,
+			Cpu:          prevStat.CPU,
+			Cpu_nano:     int64(prevStat.CPUNano),
+			System_nano:  int64(prevStat.SystemNano),
+			Mem_usage:    int64(prevStat.MemUsage),
+			Mem_limit:    int64(prevStat.MemLimit),
+			Mem_perc:     prevStat.MemPerc,
+			Net_input:    int64(prevStat.NetInput),
+			Net_output:   int64(prevStat.NetOutput),
+			Block_input:  int64(prevStat.BlockInput),
+			Block_output: int64(prevStat.BlockOutput),
+			Pids:         int64(prevStat.PIDs),
+		}
+		stats, err := iopodman.GetContainerStatsWithHistory().Call(p.Runtime.Conn, cStats)
+		if err != nil {
+			return nil, err
+		}
+		newStats := varlinkapi.ContainerStatsToLibpodContainerStats(stats)
+		// If the container wasn't running, don't include it
+		// but also suppress the error
+		if err != nil && errors.Cause(err) != libpod.ErrCtrStateInvalid {
+			return nil, err
+		}
+		if err == nil {
+			newContainerStats[c.ID()] = &newStats
+		}
+	}
+	return newContainerStats, nil
+}
diff --git a/pkg/varlinkapi/containers.go b/pkg/varlinkapi/containers.go
index 27b8d15d21..61da19c830 100644
--- a/pkg/varlinkapi/containers.go
+++ b/pkg/varlinkapi/containers.go
@@ -552,3 +552,54 @@ func (i *LibpodAPI) ContainerStateData(call iopodman.VarlinkCall, name string) e
 	}
 	return call.ReplyContainerStateData(string(b))
 }
+
+// GetContainerStatsWithHistory is a varlink endpoint that returns container stats based on current and
+// previous statistics
+func (i *LibpodAPI) GetContainerStatsWithHistory(call iopodman.VarlinkCall, prevStats iopodman.ContainerStats) error {
+	con, err := i.Runtime.LookupContainer(prevStats.Id)
+	if err != nil {
+		return call.ReplyContainerNotFound(prevStats.Id, err.Error())
+	}
+	previousStats := ContainerStatsToLibpodContainerStats(prevStats)
+	stats, err := con.GetContainerStats(&previousStats)
+	if err != nil {
+		return call.ReplyErrorOccurred(err.Error())
+	}
+	cStats := iopodman.ContainerStats{
+		Id:           stats.ContainerID,
+		Name:         stats.Name,
+		Cpu:          stats.CPU,
+		Cpu_nano:     int64(stats.CPUNano),
+		System_nano:  int64(stats.SystemNano),
+		Mem_usage:    int64(stats.MemUsage),
+		Mem_limit:    int64(stats.MemLimit),
+		Mem_perc:     stats.MemPerc,
+		Net_input:    int64(stats.NetInput),
+		Net_output:   int64(stats.NetOutput),
+		Block_input:  int64(stats.BlockInput),
+		Block_output: int64(stats.BlockOutput),
+		Pids:         int64(stats.PIDs),
+	}
+	return call.ReplyGetContainerStatsWithHistory(cStats)
+}
+
+// ContainerStatsToLibpodContainerStats converts the varlink containerstats to a libpod
+// container stats
+func ContainerStatsToLibpodContainerStats(stats iopodman.ContainerStats) libpod.ContainerStats {
+	cstats := libpod.ContainerStats{
+		ContainerID: stats.Id,
+		Name:        stats.Name,
+		CPU:         stats.Cpu,
+		CPUNano:     uint64(stats.Cpu_nano),
+		SystemNano:  uint64(stats.System_nano),
+		MemUsage:    uint64(stats.Mem_usage),
+		MemLimit:    uint64(stats.Mem_limit),
+		MemPerc:     stats.Mem_perc,
+		NetInput:    uint64(stats.Net_input),
+		NetOutput:   uint64(stats.Net_output),
+		BlockInput:  uint64(stats.Block_input),
+		BlockOutput: uint64(stats.Block_output),
+		PIDs:        uint64(stats.Pids),
+	}
+	return cstats
+}
diff --git a/pkg/varlinkapi/pods.go b/pkg/varlinkapi/pods.go
index 4ca4c42709..c79cee4c2e 100644
--- a/pkg/varlinkapi/pods.go
+++ b/pkg/varlinkapi/pods.go
@@ -2,6 +2,7 @@ package varlinkapi
 
 import (
 	"encoding/json"
+	"fmt"
 	"github.com/containers/libpod/pkg/adapter/shortcuts"
 	"github.com/containers/libpod/pkg/rootless"
 	"syscall"
@@ -299,3 +300,33 @@ func (i *LibpodAPI) PodStateData(call iopodman.VarlinkCall, name string) error {
 	}
 	return call.ReplyPodStateData(string(b))
 }
+
+// TopPod provides the top stats for a given or latest pod
+func (i *LibpodAPI) TopPod(call iopodman.VarlinkCall, name string, latest bool, descriptors []string) error {
+	var (
+		pod *libpod.Pod
+		err error
+	)
+	if latest {
+		name = "latest"
+		pod, err = i.Runtime.GetLatestPod()
+	} else {
+		pod, err = i.Runtime.LookupPod(name)
+	}
+	if err != nil {
+		return call.ReplyPodNotFound(name, err.Error())
+	}
+
+	podStatus, err := shared.GetPodStatus(pod)
+	if err != nil {
+		return call.ReplyErrorOccurred(fmt.Sprintf("unable to get status for pod %s", pod.ID()))
+	}
+	if podStatus != "Running" {
+		return call.ReplyErrorOccurred("pod top can only be used on pods with at least one running container")
+	}
+	reply, err := pod.GetPodPidInformation(descriptors)
+	if err != nil {
+		return call.ReplyErrorOccurred(err.Error())
+	}
+	return call.ReplyTopPod(reply)
+}