diff --git a/README.md b/README.md
index f6c17a6406..bbe518f524 100644
--- a/README.md
+++ b/README.md
@@ -52,6 +52,7 @@ Documentation
* [Customizing AdminController](https://github.com/javiereguiluz/EasyAdminBundle/blob/master/Resources/doc/tutorials/customizing-admin-controller.md)
* [Advanced Design Customization](https://github.com/javiereguiluz/EasyAdminBundle/blob/master/Resources/doc/tutorials/advanced-design-customization.md)
* [How to Use a WYSIWYG Editor](https://github.com/javiereguiluz/EasyAdminBundle/blob/master/Resources/doc/tutorials/wysiwyg-editor.md)
+ * [How to Upload Files and Images](https://github.com/javiereguiluz/EasyAdminBundle/blob/master/Resources/doc/tutorials/upload-files-and-images.md)
* [Tips and Tricks](https://github.com/javiereguiluz/EasyAdminBundle/blob/master/Resources/doc/tutorials/tips-and-tricks.md)
* [Configuration Reference](https://github.com/javiereguiluz/EasyAdminBundle/blob/master/Resources/doc/tutorials/configuration-reference.md)
diff --git a/Resources/doc/tutorials/upload-files-and-images.md b/Resources/doc/tutorials/upload-files-and-images.md
new file mode 100644
index 0000000000..244c7b752d
--- /dev/null
+++ b/Resources/doc/tutorials/upload-files-and-images.md
@@ -0,0 +1,388 @@
+How to Upload Files and Images
+==============================
+
+In this article you'll learn how to allow uploading files in your backends, both
+images and regular files, such as PDF files.
+
+Although EasyAdmin doesn't provide any built-in feature to upload files, it
+integrates seamlessly with [VichUploaderBundle](https://github.com/dustin10/VichUploaderBundle),
+the most popular file uploader Symfony bundle.
+
+Installing the File Uploader Bundle
+-----------------------------------
+
+1) Install the bundle:
+
+```bash
+$ composer require vich/uploader-bundle
+```
+
+2) Enable the bundle:
+
+```php
+// app/AppKernel.php
+class AppKernel extends Kernel
+{
+ public function registerBundles()
+ {
+ return array(
+ // ...
+ new Vich\UploaderBundle\VichUploaderBundle(),
+ );
+ }
+}
+```
+
+3) Add the minimal configuration that makes the bundle work:
+
+```yaml
+vich_uploader:
+ db_driver: orm
+```
+
+Uploading Image Files
+---------------------
+
+First you'll learn how to upload and preview images in the backend. Then, in the
+next section, you'll see how to upload other types of files (such as PDFs).
+
+### Configuring the Uploading of Image Files
+
+Before uploading files, you must configure the "mappings" for the VichUploaderBundle.
+These "mappings" tell the bundle where should the files be uploaded and which
+paths should be used to display them in the application.
+
+This is the configuration needed for this example:
+
+```yaml
+# app/config/config.yml
+parameters:
+ app.path.product_images: /uploads/images/product
+
+# ...
+
+vich_uploader:
+ # ...
+ mappings:
+ product_images:
+ uri_prefix: %app.path.product_images%
+ upload_destination: %kernel.root_dir%/../web/uploads/images/products
+```
+
+The `product_images` value is a freely chosen name which holds the configuration
+for a specific mapping. This value will be used later in the entity configuration.
+
+The uploaded images are stored in the directory defined in `upload_destination`.
+The `uri_prefix` option defines the base path prepended to file paths so they
+can be displayed in the application. In this example, the `uri_prefix` value is
+defined as a container parameter, because we'll reuse this value in the EasyAdmin
+configuration later.
+
+### Preparing your Entities to Persist Images
+
+Considering that the `Product` entity is already created, the first change you
+need to make is adding the `Uploadable` annotation to the entity class:
+
+```php
+use Symfony\Component\HttpFoundation\File\File;
+use Vich\UploaderBundle\Mapping\Annotation as Vich;
+
+/**
+ * @ORM\Entity
+ * @Vich\Uploadable
+ */
+class Product
+{
+ // ...
+}
+```
+
+Then, you need to add two new properties (`image` and `imageFile`):
+
+```php
+use Vich\UploaderBundle\Mapping\Annotation as Vich;
+
+/**
+ * @ORM\Entity
+ * @Vich\Uploadable
+ */
+class Product
+{
+ /**
+ * @ORM\Column(type="string", length=255)
+ * @var string
+ */
+ private $image;
+
+ /**
+ * @Vich\UploadableField(mapping="product_images", fileNameProperty="image")
+ * @var File
+ */
+ private $imageFile;
+
+ // ...
+
+ public function setImageFile(File $image = null)
+ {
+ $this->imageFile = $image;
+ }
+
+ public function getImageFile()
+ {
+ return $this->imageFile;
+ }
+
+ public function setImage($image)
+ {
+ $this->image = $image;
+ }
+
+ public function getImage()
+ {
+ return $this->image;
+ }
+}
+```
+
+The `image` property stores just the name of the uploaded image and it's
+persisted in the database. The `imageFile` property stores the binary contents
+of the image file and it's not persisted in the database (that's why it doesn't
+define a `@ORM` annotation).
+
+The `imageFile` property must define a `@Vich\UploadableField` annotation that
+configures both the "mapping" to use (`product_images` in this case) and the
+entity property that stores the image name (`image` in this case).
+
+### Displaying the Images in the `list` and `show` Views
+
+Use the special `image` type in the `list` and `show` views to display the
+contents of a property as an image:
+
+```yaml
+easy_admin:
+ entities:
+ Product:
+ # ...
+ list:
+ fields:
+ - { property: 'image', type: 'image', base_path: %app.path.product_images% }
+ # ...
+ show:
+ fields:
+ - { property: 'image', type: 'image', base_path: %app.path.product_images% }
+```
+
+The property used to display the image must be the one that stores the image path
+(`image` in this case) and not the one that stores the binary contents of the
+image (`imageFile`). Since this property only stores the image name, you must also
+define the `base_path` option to prepend the path to make the image accessible.
+
+Instead of hardcoding the `base_path` value, this example uses the
+`app.path.product_images` container parameter which also was used in the
+VichUploaderBundle configuration.
+
+### Uploading the Images in the `edit` and `new` Views
+
+The easiest way to enable uploading images in the forms of the `edit` and `new`
+views is to define the type of the property as `file`:
+
+```yaml
+easy_admin:
+ entities:
+ Product:
+ # ...
+ form:
+ fields:
+ - { property: 'imageFile', type: 'file' }
+ # ...
+```
+
+In this case, the property must be the one which stores the binary contents of
+the image (`imagefile` in this case) and not the one that stores just the name
+(`image` in this case).
+
+Although this works as expected, its behavior is too basic (for example you can't
+see a preview of the existing image before uploading a new file). In order to get
+the best experience, use `VichImageType` as the type of the property:
+
+```yaml
+easy_admin:
+ entities:
+ Product:
+ # ...
+ form:
+ fields:
+ - { property: 'imageFile', type: 'Vich\UploaderBundle\Form\Type\VichImageType' }
+ # In Symfony 2, you can use the form type shortcut
+ # - { property: 'imageFile', type: 'vich_image' }
+ # ...
+```
+
+Then, add the special form theme provided by VichUploaderBundle to the list of
+form themes used by the backend:
+
+```yaml
+easy_admin:
+ # ...
+ design:
+ form_theme: ['VichUploaderBundle:Form:fields.html.twig', 'horizontal']
+```
+
+Uploading Other Types of Files
+------------------------------
+
+Adding support for uploading other types of files (such as PDF files) is similar
+to uploading images. That's why in the next sections we'll show the required
+steps, but we won't repeat the same explanations. In this example, we'll add
+support for uploading PDFs that represent the contracts subscribed by the users.
+
+### Configuring the Uploading of Files
+
+Define the "mapping" for the new user contracts:
+
+```yaml
+parameters:
+ # ...
+ app.path.user_contracts: /uploads/files/user/contracts
+
+vich_uploader:
+ # ...
+ mappings:
+ user_contracts:
+ uri_prefix: %app.path.user_contracts%
+ upload_destination: %kernel.root_dir%/../web/uploads/files/user/contracts
+
+### Preparing your Entities to Persist Files
+
+Considering that the `User` entity already exists, add two new properties to
+store the name of the contract (`contract` property) and the binary contents of
+the PDF file (`contractFile` property). Only the first property is persisted in
+the database:
+
+```yaml
+use Doctrine\ORM\Mapping as ORM;
+use Symfony\Component\HttpFoundation\File\File;
+use Vich\UploaderBundle\Mapping\Annotation as Vich;
+
+/**
+ * @ORM\Entity
+ * @Vich\Uploadable
+ */
+class User
+{
+ /**
+ * @ORM\Column(type="string", length=255)
+ * @var string
+ */
+ private $contract;
+
+ /**
+ * @Vich\UploadableField(mapping="user_contracts", fileNameProperty="contract")
+ * @var File
+ */
+ private $contractFile;
+
+ // ... getters and setters for these properties
+}
+```
+
+### Displaying the Files in the `list` and `show` Views
+
+This is the most tricky part of adding support for file uploads. Contrary to
+images, it's not easy to provide a preview of the contents for any kind of file.
+Instead of trying to do that, we'll display a *View contract (PDF)* link in the
+`list` and `show` views.
+
+First, add the `contract` property to the list of properties to display:
+
+```yaml
+easy_admin:
+ entities:
+ User:
+ # ...
+ list:
+ fields:
+ # ...
+ - contract
+```
+
+Then, add the `template` option to define the custom template to use to render
+the contents of this property:
+
+```yaml
+easy_admin:
+ entities:
+ User:
+ # ...
+ list:
+ fields:
+ # ...
+ - { property: 'contract', template: 'contract' }
+```
+
+Now you must create the `app/Resources/views/easy_admin/contract.html.twig`
+template with this content:
+
+```twig
+View contract (PDF)
+```
+
+Reload your backend and you'll see the link to the contract PDF. However, if you
+click on the link, you won't see the file. The reason is that the `contract`
+property only stores the name of the file, but you also need the public path to
+that file (which in this case is stored in the `app.path.user_contracts` parameter).
+
+The solution is simple: you can define any number of arbitrary options for a
+property and they will be available in your custom template via the `field_options`
+option. So you just need to add a new option in the property definition:
+
+```yaml
+# Before
+- { property: 'contract', template: 'contract' }
+
+# After
+- { property: 'contract', template: 'contract', base_path: %app.path.user_contracts% }
+```
+
+Then, update the custom template to use this new option:
+
+```twig
+View contract (PDF)
+```
+
+> **TIP**
+>
+> You can also solve this issue using Symfony asset packages instead of relying
+> on EasyAdmin options. The custom template would look like this:
+>
+> ```twig
+> View contract (PDF)
+> ```
+
+### Uploading the Files in the `edit` and `new` Views
+
+Thanks to the custom `VichFileType` provided by the bundle, this is pretty
+straightforward:
+
+```yaml
+easy_admin:
+ entities:
+ Product:
+ # ...
+ form:
+ fields:
+ - { property: 'contractFile', type: 'Vich\UploaderBundle\Form\Type\VichFileType' }
+ # In Symfony 2, you can use the form type shortcut
+ # - { property: 'contractFile', type: 'vich_file' }
+ # ...
+```
+
+Don't forget to enable the custom form theme provided by VichUploaderBundle to
+improve the appearance of this file upload field:
+
+```yaml
+easy_admin:
+ # ...
+ design:
+ form_theme: ['VichUploaderBundle:Form:fields.html.twig', 'horizontal']
+```