diff --git a/cli/compile/compile.go b/cli/compile/compile.go
index 885edaecbd6..91b5d66dedb 100644
--- a/cli/compile/compile.go
+++ b/cli/compile/compile.go
@@ -26,6 +26,7 @@ import (
 	"github.com/arduino/arduino-cli/cli/errorcodes"
 	"github.com/arduino/arduino-cli/cli/instance"
 	"github.com/arduino/arduino-cli/commands/compile"
+	"github.com/arduino/arduino-cli/commands/upload"
 	"github.com/arduino/arduino-cli/common/formatter"
 	rpc "github.com/arduino/arduino-cli/rpc/commands"
 	"github.com/arduino/go-paths-helper"
@@ -34,17 +35,20 @@ import (
 )
 
 var (
-	fqbn            string   // Fully Qualified Board Name, e.g.: arduino:avr:uno.
-	showProperties  bool     // Show all build preferences used instead of compiling.
-	preprocess      bool     // Print preprocessed code to stdout.
-	buildCachePath  string   // Builds of 'core.a' are saved into this path to be cached and reused.
-	buildPath       string   // Path where to save compiled files.
-	buildProperties []string // List of custom build properties separated by commas. Or can be used multiple times for multiple properties.
-	warnings        string   // Used to tell gcc which warning level to use.
-	verbose         bool     // Turns on verbose mode.
-	quiet           bool     // Suppresses almost every output.
-	vidPid          string   // VID/PID specific build properties.
-	exportFile      string   // The compiled binary is written to this file
+	fqbn               string   // Fully Qualified Board Name, e.g.: arduino:avr:uno.
+	showProperties     bool     // Show all build preferences used instead of compiling.
+	preprocess         bool     // Print preprocessed code to stdout.
+	buildCachePath     string   // Builds of 'core.a' are saved into this path to be cached and reused.
+	buildPath          string   // Path where to save compiled files.
+	buildProperties    []string // List of custom build properties separated by commas. Or can be used multiple times for multiple properties.
+	warnings           string   // Used to tell gcc which warning level to use.
+	verbose            bool     // Turns on verbose mode.
+	quiet              bool     // Suppresses almost every output.
+	vidPid             string   // VID/PID specific build properties.
+	uploadAfterCompile bool     // Upload the binary after the compilation.
+	port               string   // Upload port, e.g.: COM10 or /dev/ttyACM0.
+	verify             bool     // Upload, verify uploaded binary after the upload.
+	exportFile         string   // The compiled binary is written to this file
 )
 
 // NewCommand created a new `compile` command
@@ -71,6 +75,9 @@ func NewCommand() *cobra.Command {
 		`Optional, can be "none", "default", "more" and "all". Defaults to "none". Used to tell gcc which warning level to use (-W flag).`)
 	command.Flags().BoolVarP(&verbose, "verbose", "v", false, "Optional, turns on verbose mode.")
 	command.Flags().BoolVar(&quiet, "quiet", false, "Optional, supresses almost every output.")
+	command.Flags().BoolVarP(&uploadAfterCompile, "upload", "u", false, "Upload the binary after the compilation.")
+	command.Flags().StringVarP(&port, "port", "p", "", "Upload port, e.g.: COM10 or /dev/ttyACM0")
+	command.Flags().BoolVarP(&verify, "verify", "t", false, "Verify uploaded binary after the upload.")
 	command.Flags().StringVar(&vidPid, "vid-pid", "", "When specified, VID/PID specific build properties are used, if boards supports them.")
 
 	return command
@@ -106,6 +113,23 @@ func run(cmd *cobra.Command, args []string) {
 		formatter.PrintError(err, "Error during build")
 		os.Exit(errorcodes.ErrGeneric)
 	}
+
+	if uploadAfterCompile {
+		_, err := upload.Upload(context.Background(), &rpc.UploadReq{
+			Instance:   instance,
+			Fqbn:       fqbn,
+			SketchPath: sketchPath.String(),
+			Port:       port,
+			Verbose:    verbose,
+			Verify:     verify,
+			ImportFile: exportFile,
+		}, os.Stdout, os.Stderr)
+
+		if err != nil {
+			formatter.PrintError(err, "Error during Upload")
+			os.Exit(errorcodes.ErrGeneric)
+		}
+	}
 }
 
 // initSketchPath returns the current working directory
diff --git a/test/test_compile.py b/test/test_compile.py
new file mode 100644
index 00000000000..4034b40718d
--- /dev/null
+++ b/test/test_compile.py
@@ -0,0 +1,120 @@
+# This file is part of arduino-cli.
+
+# Copyright 2019 ARDUINO SA (http://www.arduino.cc/)
+
+# This software is released under the GNU General Public License version 3,
+# which covers the main part of arduino-cli.
+# The terms of this license can be found at:
+# https://www.gnu.org/licenses/gpl-3.0.en.html
+
+# You can be released from the requirements of the above licenses by purchasing
+# a commercial license. Buying such a license is mandatory if you want to modify or
+# otherwise use the software for commercial activities involving the Arduino
+# software without disclosing the source code of your own applications. To purchase
+# a commercial license, send an email to license@arduino.cc.
+import pytest
+import json
+import os
+
+from .common import running_on_ci
+
+
+def test_compile_without_fqbn(run_command):
+    # Init the environment explicitly
+    result = run_command("core update-index")
+    assert result.ok
+
+    # Download latest AVR
+    result = run_command("core install arduino:avr")
+    assert result.ok
+
+    # Build sketch without FQBN
+    result = run_command("compile")
+    assert result.failed
+
+
+def test_compile_with_simple_sketch(run_command, data_dir):
+    # Init the environment explicitly
+    result = run_command("core update-index")
+    assert result.ok
+
+    # # Download latest AVR
+    result = run_command("core install arduino:avr")
+    assert result.ok
+
+    sketch_path = os.path.join(data_dir, "CompileIntegrationTest")
+
+    # Create a test sketch
+    result = run_command("sketch new CompileIntegrationTest")
+    assert result.ok
+    assert "Sketch created in: {}".format(sketch_path) in result.stdout
+
+    # Build sketch for arduino:avr:uno
+    result = run_command("compile -b arduino:avr:uno {}".format(sketch_path))
+    assert result.ok
+    assert "Sketch uses" in result.stdout
+
+
+@pytest.mark.skipif(running_on_ci(), reason="VMs have no serial ports")
+def test_compile_and_compile_combo(run_command, data_dir):
+
+    # Init the environment explicitly
+    result = run_command("core update-index")
+    assert result.ok
+
+    # Install required core(s)
+    result = run_command("core install arduino:avr")
+    # result = run_command("core install arduino:samd")
+    assert result.ok
+
+    # Create a test sketch
+    sketch_path = os.path.join(data_dir, "CompileAndUploadIntegrationTest")
+    result = run_command("sketch new CompileAndUploadIntegrationTest")
+    assert result.ok
+    assert "Sketch created in: {}".format(sketch_path) in result.stdout
+
+    #
+    # Build a list of detected boards to test, if any.
+    #
+    result = run_command("board list --format json")
+    assert result.ok
+
+    #
+    # The `board list --format json` returns a JSON that looks like to the following:
+    #
+    # [
+    #     {
+    #       "address": "/dev/cu.usbmodem14201",
+    #       "protocol": "serial",
+    #       "protocol_label": "Serial Port (USB)",
+    #       "boards": [
+    #         {
+    #           "name": "Arduino NANO 33 IoT",
+    #           "FQBN": "arduino:samd:nano_33_iot"
+    #         }
+    #       ]
+    #     }
+    #   ]
+
+    detected_boards = []    
+
+    ports = json.loads(result.stdout)
+    assert isinstance(ports, list)
+    for port in ports:
+        boards = port.get('boards')
+        assert isinstance(boards, list)
+        for board in boards:
+            detected_boards.append(dict(address=port.get('address'), fqbn=board.get('FQBN')))
+
+    assert len(detected_boards) >= 1, "There are no boards available for testing"
+
+    # Build sketch for each detected board
+    for board in detected_boards:  
+        result = run_command(
+            "compile -b {fqbn} --upload -p {address} {sketch_path}".format(
+                fqbn=board.get('fqbn'),
+                address=board.get('address'),
+                sketch_path=sketch_path)
+        )
+        assert result.ok
+        assert "Verify successful" in result.stdout