Normally the add call is sufficient. 
Note: a BorderLayout can only contain one component in each location. So if you add another component in the NORTH location, your button will not be visible.
Second note: by default a JPanel does not have a BorderLayout but a FlowLayout. Have you set a BorderLayout on that specific panel ? Otherwise the BorderLayout#NORTH constraint is incorrect
All the validate,revalidate,repaint calls can be removed
Edit
It seems some sort of validation is needed after all. I was under the impression that Swing should be smart enough to listen for the event when something is added to a Container, and  update whatever is necessary (a bit similar to updating a TableModel updates the JTable based on events, without the need to call repaint or the likes on the JTable).
However, when trying this in an SSCCE, I came to the following code (different versions, only post the most elaborate version)
- without the scroll-pane, the validatecalls seem to have no effect. I actually need to callpackagain to make the new labels visible (not included in the SSCCE, but removing the scrollpane from the code is trivial)
- with the scroll-pane, the - validatecall has an effect
 - import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class AddLabelsAtRuntime {
  private int fLabelCounter = 0;
  private JPanel fLabelPanel;
  private final JFrame fTestFrame;
  public AddLabelsAtRuntime() {
    fLabelPanel = new JPanel(  );
    BoxLayout boxLayout = new BoxLayout( fLabelPanel, BoxLayout.PAGE_AXIS );
    fLabelPanel.setLayout( boxLayout );
    fTestFrame = new JFrame( "Dynamically add labels" );
  }
  private JFrame createUI(){
    Container contentPane = fTestFrame.getContentPane();
    contentPane.setLayout( new BorderLayout() );
    JScrollPane scrollPane = new JScrollPane( fLabelPanel );
    scrollPane.setPreferredSize( new Dimension( 200, 200 ) );
    contentPane.add( scrollPane, BorderLayout.CENTER );
    contentPane.add( createButtonPanel(), BorderLayout.SOUTH );
    fTestFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
    fTestFrame.pack();
    return fTestFrame;
  }
  private void addLabel(){
    fLabelPanel.add( new JLabel( "Label " + ++fLabelCounter ) );
  }
  private JPanel createButtonPanel(){
    JPanel buttonPanel = new JPanel(  );
    BoxLayout boxLayout = new BoxLayout( buttonPanel, BoxLayout.LINE_AXIS );
    buttonPanel.setLayout( boxLayout );
    JButton validateButton = new JButton( "Add + validate" );
    validateButton.addActionListener( new ActionListener() {
      @Override
      public void actionPerformed( ActionEvent e ) {
        addLabel();
        fLabelPanel.validate();
        fTestFrame.validate();
      }
    } );
    buttonPanel.add( validateButton );
    JButton noValidateButton = new JButton( "Add" );
    noValidateButton.addActionListener( new ActionListener() {
      @Override
      public void actionPerformed( ActionEvent e ) {
        addLabel();
      }
    } );
    buttonPanel.add( noValidateButton );
    JButton packButton = new JButton( "Add + pack" );
    packButton.addActionListener( new ActionListener() {
      @Override
      public void actionPerformed( ActionEvent e ) {
        addLabel();
        fTestFrame.pack();
      }
    } );
    buttonPanel.add( packButton );
    return buttonPanel;
  }
  public static void main( String[] args ) {
    EventQueue.invokeLater( new Runnable() {
      @Override
      public void run() {
        AddLabelsAtRuntime addLabelsAtRuntime = new AddLabelsAtRuntime();
        addLabelsAtRuntime.createUI().setVisible( true );
      }
    } );
  }
}